Libical API Documentation 4.0 UNRELEASED Go to the stable 3.0 documentation
Loading...
Searching...
No Matches
icalclassify.c
Go to the documentation of this file.
1/*======================================================================
2 FILE: icalclassify.c
3 CREATOR: ebusboom 23 aug 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
13
14#ifdef HAVE_CONFIG_H
15#include <config.h>
16#endif
17
18#include "icalclassify.h"
19#include "icalerror.h"
20#include "icalmemory.h"
21
22#include <assert.h>
23#include <ctype.h>
24#include <stdlib.h>
25
26struct icalclassify_parts {
27 icalcomponent *c;
28 icalcomponent_kind inner_kind;
29 icalproperty_method method;
30 char *organizer;
31 icalparameter_partstat reply_partstat;
32 char *reply_attendee;
33 char *uid;
34 int sequence;
35 struct icaltimetype dtstamp;
36 struct icaltimetype recurrence_id;
37};
38
39char *icalclassify_lowercase(const char *str)
40{
41 char *p = 0;
42 char *xnew;
43
44 if (str == 0) {
45 return 0;
46 }
47
48 xnew = strdup(str);
49 if (!xnew) {
51 return 0;
52 }
53 for (p = xnew; *p != 0; p++) {
54 *p = tolower((int)*p);
55 }
56
57 return xnew;
58}
59
64
65icalcomponent *icalclassify_find_overlaps(icalset *set, icalcomponent *comp)
66{
67 icalcomponent *return_set;
68 icalcomponent *c;
69 struct icaltime_span compspan;
70
72 compspan = icalcomponent_get_span(comp);
73
74 if (icalerrno != ICAL_NO_ERROR) {
75 return 0;
76 }
77
79
80 for (c = icalset_get_first_component(set); c != 0; c = icalset_get_next_component(set)) {
82
83 struct icaltime_span span = icalcomponent_get_span(c);
84
85 if (icalerrno != ICAL_NO_ERROR) {
86 continue;
87 }
88
89 if (compspan.start < span.end && compspan.end > span.start) {
90 icalcomponent *clone = icalcomponent_clone(c);
91
92 icalcomponent_add_component(return_set, clone);
93 }
94 }
95
97 return return_set;
98 } else {
99 icalcomponent_free(return_set);
100 return 0;
101 }
102}
103
104icalproperty *icalclassify_find_attendee(const icalcomponent *c, const char *attendee)
105{
106 icalproperty *p;
107 icalcomponent *inner;
108 char *lattendee;
109 const char *upn;
110
111 if (attendee == 0) {
112 return 0;
113 }
114
115 lattendee = icalclassify_lowercase(attendee);
116 if (!lattendee) {
117 return 0;
118 }
119 upn = strchr(lattendee, ':');
120
121 if (upn == 0) {
122 upn = lattendee;
123 } else {
124 upn++; /* skip the ";" */
125 }
126
128
129 for (p = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
130 p != 0;
131 p = icalcomponent_get_next_property(inner, ICAL_ATTENDEE_PROPERTY)) {
132 const char *this_upn;
133 char *this_attendee = icalclassify_lowercase(icalproperty_get_attendee(p));
134
135 if (!this_attendee) {
136 continue;
137 }
138
139 this_upn = strchr(this_attendee, ':');
140
141 if (this_upn == 0) {
142 free(this_attendee);
143 continue;
144 } else {
145 this_upn++;
146 }
147
148 if (strcmp(this_upn, upn) == 0) {
149 free(lattendee);
150 free(this_attendee);
151 return p;
152 }
153
154 free(this_attendee);
155 }
156 free(lattendee);
157
158 return 0;
159}
160
161void icalssutil_free_parts(struct icalclassify_parts *parts)
162{
163 if (parts == 0) {
164 return;
165 }
166
167 if (parts->organizer != 0) {
168 free(parts->organizer);
169 }
170
171 if (parts->uid != 0) {
172 free(parts->uid);
173 }
174
175 if (parts->reply_attendee) {
176 free(parts->reply_attendee);
177 }
178}
179
180void icalssutil_get_parts(icalcomponent *c, struct icalclassify_parts *parts)
181{
182 icalproperty *p;
183 icalcomponent *inner;
184
185 memset(parts, 0, sizeof(struct icalclassify_parts));
186
187 parts->method = ICAL_METHOD_NONE;
188 parts->sequence = 0;
189 parts->reply_partstat = ICAL_PARTSTAT_NONE;
190
191 if (c == 0) {
192 return;
193 }
194
195 parts->c = c;
196
197 p = icalcomponent_get_first_property(c, ICAL_METHOD_PROPERTY);
198 if (p != 0) {
199 parts->method = icalproperty_get_method(p);
200 }
201
203
204 parts->inner_kind = icalcomponent_isa(inner);
205
206 p = icalcomponent_get_first_property(inner, ICAL_ORGANIZER_PROPERTY);
207 if (p != 0) {
208 const char *p_organizer = icalproperty_get_organizer(p);
209
210 if (p_organizer != 0) {
211 parts->organizer = strdup(p_organizer);
212 }
213 }
214
215 p = icalcomponent_get_first_property(inner, ICAL_SEQUENCE_PROPERTY);
216 if (p != 0) {
217 parts->sequence = icalproperty_get_sequence(p);
218 }
219
220 p = icalcomponent_get_first_property(inner, ICAL_UID_PROPERTY);
221 if (p != 0) {
222 const char *p_uid = icalproperty_get_uid(p);
223
224 if (p_uid != 0) {
225 parts->uid = strdup(p_uid);
226 }
227 }
228
229 p = icalcomponent_get_first_property(inner, ICAL_RECURRENCEID_PROPERTY);
230 if (p != 0) {
231 parts->recurrence_id = icalproperty_get_recurrenceid(p);
232 }
233
234 p = icalcomponent_get_first_property(inner, ICAL_DTSTAMP_PROPERTY);
235 if (p != 0) {
236 parts->dtstamp = icalproperty_get_dtstamp(p);
237 }
238
239 if (parts->method == ICAL_METHOD_REPLY) {
240 p = icalcomponent_get_first_property(inner, ICAL_ATTENDEE_PROPERTY);
241
242 if (p != 0) {
243 const char *attendee = 0;
244
245 icalparameter *param = icalproperty_get_first_parameter(p, ICAL_PARTSTAT_PARAMETER);
246 if (param != 0) {
247 parts->reply_partstat = icalparameter_get_partstat(param);
248 }
249 attendee = icalproperty_get_attendee(p);
250 if (attendee) {
251 parts->reply_attendee = strdup(attendee);
252 }
253 }
254 }
255}
256
257static bool icalssutil_is_rescheduled(const icalcomponent *a, const icalcomponent *b)
258{
259 icalcomponent *i1, *i2;
260 const char *temp1, *temp2;
261 int i;
262
263 icalproperty_kind kind_array[] = {
264 ICAL_DTSTART_PROPERTY,
265 ICAL_DTEND_PROPERTY,
266 ICAL_DURATION_PROPERTY,
267 ICAL_DUE_PROPERTY,
268 ICAL_RRULE_PROPERTY,
269 ICAL_RDATE_PROPERTY,
270 ICAL_EXRULE_PROPERTY,
271 ICAL_EXDATE_PROPERTY,
272 ICAL_NO_PROPERTY};
273
276
277 for (i = 0; kind_array[i] != ICAL_NO_PROPERTY; i++) {
278 int cmp;
279
280 icalproperty *p1 = icalcomponent_get_first_property(i1, kind_array[i]);
281 icalproperty *p2 = icalcomponent_get_first_property(i2, kind_array[i]);
282
283 if ((p1 != 0) ^ (p2 != 0)) {
284 /* Return true if the property exists in one component and not
285 the other */
286 return true;
287 } else if (!p1 && !p2) {
288 continue;
289 }
290
293 cmp = strcmp(temp1, temp2);
294 icalmemory_free_buffer((char *)temp1);
295 icalmemory_free_buffer((char *)temp2);
296
297 if (p1 && cmp != 0) {
298 return true;
299 }
300 }
301
302 return false;
303}
304
305#define icalclassify_pre \
306 int rtrn = 0;
307
308#define icalclassify_post \
309 return rtrn;
310
311int icalclassify_publish_new(const struct icalclassify_parts *comp,
312 const struct icalclassify_parts *match, const char *user)
313{
314 icalclassify_pre;
315 _unused(user);
316
317 if (comp->method == ICAL_METHOD_PUBLISH &&
318 match == 0 && comp->inner_kind != ICAL_VFREEBUSY_COMPONENT) {
319 rtrn = 1;
320 }
321
322 icalclassify_post;
323}
324
325int icalclassify_publish_update(const struct icalclassify_parts *comp,
326 const struct icalclassify_parts *match, const char *user)
327{
328 icalclassify_pre;
329 _unused(user);
330
331 if (comp->method == ICAL_METHOD_PUBLISH &&
332 match != 0 && comp->inner_kind != ICAL_VFREEBUSY_COMPONENT) {
333 rtrn = 1;
334 }
335
336 icalclassify_post;
337}
338
339int icalclassify_publish_freebusy(const struct icalclassify_parts *comp,
340 const struct icalclassify_parts *match, const char *user)
341{
342 icalclassify_pre;
343
344 _unused(match);
345 _unused(user);
346 if (comp->method == ICAL_METHOD_PUBLISH && comp->inner_kind == ICAL_VFREEBUSY_COMPONENT) {
347 rtrn = 1;
348 }
349
350 icalclassify_post;
351}
352
353int icalclassify_request_new(const struct icalclassify_parts *comp,
354 const struct icalclassify_parts *match, const char *user)
355{
356 /* Method is REQUEST, and there is no match */
357
358 icalclassify_pre _unused(user);
359
360 if (match->c == 0 && comp->method == ICAL_METHOD_REQUEST) {
361 rtrn = 1;
362 }
363
364 icalclassify_post
365}
366
367int icalclassify_request_update(const struct icalclassify_parts *comp,
368 const struct icalclassify_parts *match, const char *user)
369{
370 /* REQUEST method, Higher SEQUENCE than match, and all
371 time-related properties are unchanged */
372
373 icalclassify_pre _unused(user);
374
375 if (match != 0 &&
376 comp->sequence >= match->sequence && !icalssutil_is_rescheduled(comp->c, match->c)) {
377 rtrn = 1;
378 }
379
380 icalclassify_post
381}
382
383int icalclassify_request_reschedule(const struct icalclassify_parts *comp,
384 const struct icalclassify_parts *match, const char *user)
385{
386 /* REQUEST method, Higher SEQUENCE than match, and one or more
387 time-related properties are changed */
388 icalclassify_pre _unused(user);
389
390 if (match->c != 0 &&
391 comp->sequence > match->sequence && icalssutil_is_rescheduled(comp->c, match->c)) {
392 rtrn = 1;
393 }
394
395 icalclassify_post
396}
397
398int icalclassify_request_delegate(const struct icalclassify_parts *comp,
399 const struct icalclassify_parts *match, const char *user)
400{
401 icalproperty *attendee;
402 const icalparameter *param;
403
404 icalclassify_pre;
405 _unused(match);
406
407 attendee = icalclassify_find_attendee(comp->c, user);
408
409 if (attendee == 0) {
410 return 0;
411 }
412
413 param = icalproperty_get_first_parameter(attendee, ICAL_DELEGATEDFROM_PARAMETER);
414
415 if (param != 0) {
416 rtrn = 1;
417 }
418
419 icalclassify_post
420}
421
422int icalclassify_request_new_organizer(const struct icalclassify_parts *comp,
423 const struct icalclassify_parts *match, const char *user)
424{
425 /* Organizer has changed between match and component */
426 icalclassify_pre _unused(comp);
427 _unused(match);
428 _unused(user);
429
431 icalclassify_post
432}
433
434int icalclassify_request_status(const struct icalclassify_parts *comp,
435 const struct icalclassify_parts *match, const char *user)
436{
437 icalclassify_pre _unused(comp);
438 _unused(match);
439 _unused(user);
440
442 icalclassify_post
443}
444
445int icalclassify_request_forward(const struct icalclassify_parts *comp,
446 const struct icalclassify_parts *match, const char *user)
447{
448 icalclassify_pre _unused(comp);
449 _unused(match);
450 _unused(user);
451
453 icalclassify_post
454}
455
456int icalclassify_request_freebusy(const struct icalclassify_parts *comp,
457 const struct icalclassify_parts *match, const char *user)
458{
459 icalclassify_pre _unused(comp);
460 _unused(match);
461 _unused(user);
462
464 icalclassify_post
465}
466
467int icalclassify_reply_accept(const struct icalclassify_parts *comp,
468 const struct icalclassify_parts *match, const char *user)
469{
470 const icalproperty *attendee;
471
472 icalclassify_pre;
473 _unused(user);
474
475 attendee = icalclassify_find_attendee(match->c, comp->reply_attendee);
476
477 if (attendee != 0 && comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED) {
478 rtrn = 1;
479 }
480
481 icalclassify_post
482}
483
484int icalclassify_reply_decline(const struct icalclassify_parts *comp,
485 const struct icalclassify_parts *match, const char *user)
486{
487 const icalproperty *attendee;
488
489 icalclassify_pre;
490 _unused(user);
491
492 attendee = icalclassify_find_attendee(match->c, comp->reply_attendee);
493
494 if (attendee != 0 && comp->reply_partstat == ICAL_PARTSTAT_DECLINED) {
495 rtrn = 1;
496 }
497 icalclassify_post
498}
499
500int icalclassify_reply_delegate(const struct icalclassify_parts *comp,
501 const struct icalclassify_parts *match, const char *user)
502{
503 const icalproperty *attendee;
504
505 icalclassify_pre;
506 _unused(user);
507
508 attendee = icalclassify_find_attendee(match->c, comp->reply_attendee);
509
510 if (attendee != 0 && comp->reply_partstat == ICAL_PARTSTAT_DELEGATED) {
511 rtrn = 1;
512 }
513 icalclassify_post
514}
515
516int icalclassify_reply_crasher_accept(const struct icalclassify_parts *comp,
517 const struct icalclassify_parts *match, const char *user)
518{
519 const icalproperty *attendee;
520
521 icalclassify_pre;
522 _unused(user);
523
524 attendee = icalclassify_find_attendee(match->c, comp->reply_attendee);
525
526 if (attendee == 0 && comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED) {
527 rtrn = 1;
528 }
529 icalclassify_post
530}
531
532int icalclassify_reply_crasher_decline(const struct icalclassify_parts *comp,
533 const struct icalclassify_parts *match, const char *user)
534{
535 const icalproperty *attendee;
536
537 icalclassify_pre;
538 _unused(user);
539
540 attendee = icalclassify_find_attendee(match->c, comp->reply_attendee);
541
542 if (attendee == 0 && comp->reply_partstat == ICAL_PARTSTAT_DECLINED) {
543 rtrn = 1;
544 }
545 icalclassify_post
546}
547
548int icalclassify_add_instance(const struct icalclassify_parts *comp,
549 const struct icalclassify_parts *match, const char *user)
550{
551 icalclassify_pre _unused(match);
552 _unused(user);
553
554 if (comp->method == ICAL_METHOD_ADD) {
555 rtrn = 1;
556 }
557 icalclassify_post
558}
559
560int icalclassify_cancel_event(const struct icalclassify_parts *comp,
561 const struct icalclassify_parts *match, const char *user)
562{
563 icalclassify_pre _unused(match);
564 _unused(user);
565 if (comp->method == ICAL_METHOD_CANCEL) {
566 rtrn = 1;
567 }
568 icalclassify_post
569}
570
571int icalclassify_cancel_instance(const struct icalclassify_parts *comp,
572 const struct icalclassify_parts *match, const char *user)
573{
574 icalclassify_pre _unused(match);
575 _unused(user);
576 if (comp->method == ICAL_METHOD_CANCEL) {
577 rtrn = 1;
578 }
579 icalclassify_post
580}
581
582int icalclassify_cancel_all(const struct icalclassify_parts *comp,
583 const struct icalclassify_parts *match, const char *user)
584{
585 icalclassify_pre _unused(match);
586 _unused(user);
587 if (comp->method == ICAL_METHOD_CANCEL) {
588 rtrn = 1;
589 }
590 icalclassify_post
591}
592
593int icalclassify_refesh(const struct icalclassify_parts *comp,
594 const struct icalclassify_parts *match, const char *user)
595{
596 icalclassify_pre _unused(match);
597 _unused(user);
598 if (comp->method == ICAL_METHOD_REFRESH) {
599 rtrn = 1;
600 }
601 icalclassify_post
602}
603
604int icalclassify_counter(const struct icalclassify_parts *comp,
605 const struct icalclassify_parts *match, const char *user)
606{
607 icalclassify_pre _unused(match);
608 _unused(user);
609 if (comp->method == ICAL_METHOD_COUNTER) {
610 rtrn = 1;
611 }
612 icalclassify_post
613}
614
615int icalclassify_delinecounter(const struct icalclassify_parts *comp,
616 const struct icalclassify_parts *match, const char *user)
617{
618 icalclassify_pre _unused(match);
619 _unused(user);
620
621 if (comp->method == ICAL_METHOD_DECLINECOUNTER) {
622 rtrn = 1;
623 }
624
625 icalclassify_post
626}
627
628static const struct icalclassify_map { //NOLINT(clang-analyzer-optin.performance.Padding) too much work to change all the initialization
629 icalproperty_method method;
630 int (*fn)(const struct icalclassify_parts *comp, const struct icalclassify_parts *match,
631 const char *user);
632 icalproperty_xlicclass class;
633} icalclassify_map[] = {
634 {ICAL_METHOD_PUBLISH, icalclassify_publish_new, ICAL_XLICCLASS_PUBLISHNEW},
635 {ICAL_METHOD_PUBLISH, icalclassify_publish_update, ICAL_XLICCLASS_PUBLISHUPDATE},
636 {ICAL_METHOD_PUBLISH, icalclassify_publish_freebusy, ICAL_XLICCLASS_PUBLISHFREEBUSY},
637 {ICAL_METHOD_REQUEST, icalclassify_request_delegate, ICAL_XLICCLASS_REQUESTDELEGATE},
638 {ICAL_METHOD_REQUEST, icalclassify_request_new, ICAL_XLICCLASS_REQUESTNEW},
639 {ICAL_METHOD_REQUEST, icalclassify_request_update, ICAL_XLICCLASS_REQUESTUPDATE},
640 {ICAL_METHOD_REQUEST, icalclassify_request_reschedule, ICAL_XLICCLASS_REQUESTRESCHEDULE},
641 {ICAL_METHOD_REQUEST, icalclassify_request_new_organizer, ICAL_XLICCLASS_REQUESTNEWORGANIZER},
642 {ICAL_METHOD_REQUEST, icalclassify_request_forward, ICAL_XLICCLASS_REQUESTFORWARD},
643 {ICAL_METHOD_REQUEST, icalclassify_request_status, ICAL_XLICCLASS_REQUESTSTATUS},
644 {ICAL_METHOD_REQUEST, icalclassify_request_freebusy, ICAL_XLICCLASS_REQUESTFREEBUSY},
645 {ICAL_METHOD_REPLY, icalclassify_reply_accept, ICAL_XLICCLASS_REPLYACCEPT},
646 {ICAL_METHOD_REPLY, icalclassify_reply_decline, ICAL_XLICCLASS_REPLYDECLINE},
647 {ICAL_METHOD_REPLY, icalclassify_reply_delegate, ICAL_XLICCLASS_REPLYDELEGATE},
648 {ICAL_METHOD_REPLY, icalclassify_reply_crasher_accept, ICAL_XLICCLASS_REPLYCRASHERACCEPT},
649 {ICAL_METHOD_REPLY, icalclassify_reply_crasher_decline, ICAL_XLICCLASS_REPLYCRASHERDECLINE},
650 {ICAL_METHOD_ADD, icalclassify_add_instance, ICAL_XLICCLASS_ADDINSTANCE},
651 {ICAL_METHOD_CANCEL, icalclassify_cancel_event, ICAL_XLICCLASS_CANCELEVENT},
652 {ICAL_METHOD_CANCEL, icalclassify_cancel_instance, ICAL_XLICCLASS_CANCELINSTANCE},
653 {ICAL_METHOD_CANCEL, icalclassify_cancel_all, ICAL_XLICCLASS_CANCELALL},
654 {ICAL_METHOD_REFRESH, icalclassify_refesh, ICAL_XLICCLASS_REFRESH},
655 {ICAL_METHOD_COUNTER, icalclassify_counter, ICAL_XLICCLASS_COUNTER},
656 {ICAL_METHOD_DECLINECOUNTER, icalclassify_delinecounter, ICAL_XLICCLASS_DECLINECOUNTER},
657 {ICAL_METHOD_NONE, NULL, ICAL_XLICCLASS_NONE}};
658
659icalproperty_xlicclass icalclassify(icalcomponent *c, icalcomponent *match, const char *user)
660{
661 const icalcomponent *inner;
662 icalproperty *p;
663 icalproperty_method method;
664 icalproperty_xlicclass class = ICAL_XLICCLASS_UNKNOWN;
665
666 int i;
667
668 struct icalclassify_parts comp_parts;
669 struct icalclassify_parts match_parts;
670
672
673 if (inner == 0) {
674 return ICAL_XLICCLASS_NONE;
675 }
676
677 icalssutil_get_parts(c, &comp_parts);
678 icalssutil_get_parts(match, &match_parts);
679
680 /* Determine if the incoming component is obsoleted by the match */
681 if (match != 0 && (comp_parts.method == ICAL_METHOD_REQUEST)) {
682 assert(!((icaltime_is_utc(comp_parts.dtstamp) == 1) ^
683 (icaltime_is_utc(match_parts.dtstamp) == 1)));
684
685 if (comp_parts.sequence < match_parts.sequence &&
686 icaltime_compare(comp_parts.dtstamp, match_parts.dtstamp) > 0) {
687 /* comp has a smaller sequence and a later DTSTAMP */
688 class = ICAL_XLICCLASS_MISSEQUENCED;
689 goto CLEANUP;
690 }
691
692 if ((comp_parts.sequence < match_parts.sequence) ||
693 (comp_parts.sequence == match_parts.sequence &&
694 icaltime_compare(comp_parts.dtstamp, match_parts.dtstamp) <= 0)) {
695 class = ICAL_XLICCLASS_OBSOLETE;
696 goto CLEANUP;
697 }
698 }
699
700 p = icalcomponent_get_first_property(c, ICAL_METHOD_PROPERTY);
701 if (p == 0) {
702 class = ICAL_XLICCLASS_UNKNOWN;
703 goto CLEANUP;
704 }
705 method = icalproperty_get_method(p);
706
707 for (i = 0; icalclassify_map[i].method != ICAL_METHOD_NONE; i++) {
708 if (icalclassify_map[i].method == method) {
709 if ((*(icalclassify_map[i].fn))(&comp_parts, &match_parts, user) == 1) {
710 class = icalclassify_map[i].class;
711 break;
712 }
713 }
714 }
715
716CLEANUP:
717 icalssutil_free_parts(&comp_parts);
718 icalssutil_free_parts(&match_parts);
719
720 return class;
721}
icalcomponent * icalclassify_find_overlaps(icalset *set, icalcomponent *comp)
Defines functions for classification.
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)
icalcomponent * icalcomponent_new(icalcomponent_kind kind)
icaltime_span icalcomponent_get_span(icalcomponent *comp)
icalcomponent * icalcomponent_get_first_real_component(const icalcomponent *c)
icalcomponent * icalcomponent_clone(const icalcomponent *old)
icalcomponent_kind icalcomponent_isa(const icalcomponent *component)
void icalcomponent_free(icalcomponent *c)
void icalcomponent_add_component(icalcomponent *parent, icalcomponent *child)
icalproperty * icalcomponent_get_next_property(icalcomponent *c, icalproperty_kind kind)
int icalcomponent_count_components(icalcomponent *component, icalcomponent_kind kind)
icalcomponent_kind
Definition icalenums.h:29
@ ICAL_XROOT_COMPONENT
Definition icalenums.h:32
@ ICAL_VFREEBUSY_COMPONENT
Definition icalenums.h:39
@ ICAL_ANY_COMPONENT
Definition icalenums.h:31
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
Definition icalerror.c:90
void icalerror_clear_errno(void)
Resets icalerrno to ICAL_NO_ERROR.
Definition icalerror.c:85
Error handling for libical.
@ ICAL_NEWFAILED_ERROR
Definition icalerror.h:50
@ ICAL_NO_ERROR
Definition icalerror.h:44
@ ICAL_UNIMPLEMENTED_ERROR
Definition icalerror.h:71
#define icalerrno
Access the current icalerrno value.
Definition icalerror.h:130
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition icalmemory.c:353
Common memory management routines.
char * icalproperty_as_ical_string_r(icalproperty *prop)
icalparameter * icalproperty_get_first_parameter(icalproperty *p, icalparameter_kind kind)
icalcomponent * icalset_get_first_component(icalset *set)
Definition icalset.c:403
icalcomponent * icalset_get_next_component(icalset *set)
Definition icalset.c:408
bool icaltime_is_utc(const struct icaltimetype t)
Definition icaltime.c:621
int icaltime_compare(const struct icaltimetype a_in, const struct icaltimetype b_in)
Definition icaltime.c:635