$darkmode
Libical API Documentation 4.0 STABLE VERSION Visit the v3.0 documentation
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 
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 
26 struct 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 
39 char *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 
65 icalcomponent *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 
96  if (icalcomponent_count_components(return_set, ICAL_ANY_COMPONENT) != 0) {
97  return return_set;
98  } else {
99  icalcomponent_free(return_set);
100  return 0;
101  }
102 }
103 
104 icalproperty *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 
161 void 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 
180 void 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 
257 static 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 
291  temp1 = icalproperty_as_ical_string_r(p1);
292  temp2 = icalproperty_as_ical_string_r(p2);
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 
311 int 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 
325 int 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 
339 int 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 
353 int 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 
367 int 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 
383 int 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 
398 int 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 
422 int 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 
434 int 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 
445 int 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 
456 int 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 
467 int 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 
484 int 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 
500 int 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 
516 int 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 
532 int 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 
548 int 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 
560 int 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 
571 int 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 
582 int 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 
593 int 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 
604 int 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 
615 int 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 
628 static 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 
659 icalproperty_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 
716 CLEANUP:
717  icalssutil_free_parts(&comp_parts);
718  icalssutil_free_parts(&match_parts);
719 
720  return class;
721 }
Defines functions for classification.
Common memory management routines.
icalproperty * icalcomponent_get_next_property(icalcomponent *c, icalproperty_kind kind)
int icalcomponent_count_components(icalcomponent *component, icalcomponent_kind kind)
void icalcomponent_add_component(icalcomponent *parent, icalcomponent *child)
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Definition: icalmemory.c:355
icalcomponent * icalcomponent_clone(const icalcomponent *old)
bool icaltime_is_utc(const struct icaltimetype t)
Definition: icaltime.c:625
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
void icalerror_clear_errno(void)
Resets icalerrno to ICAL_NO_ERROR.
Definition: icalerror.c:85
int icaltime_compare(const struct icaltimetype a_in, const struct icaltimetype b_in)
Definition: icaltime.c:639
Error handling for libical.
icaltime_span icalcomponent_get_span(icalcomponent *comp)
char * icalproperty_as_ical_string_r(icalproperty *prop)
Definition: icalproperty.c:371
icalcomponent * icalcomponent_new(icalcomponent_kind kind)
icalcomponent * icalclassify_find_overlaps(icalset *set, icalcomponent *comp)
Definition: icalclassify.c:65
icalparameter * icalproperty_get_first_parameter(icalproperty *p, icalparameter_kind kind)
Definition: icalproperty.c:704
icalcomponent_kind
Definition: icalenums.h:28
icalcomponent_kind icalcomponent_isa(const icalcomponent *component)
#define icalerrno
Access the current icalerrno value.
Definition: icalerror.h:133
icalcomponent * icalset_get_first_component(icalset *set)
Definition: icalset.c:403
void icalcomponent_free(icalcomponent *c)
icalcomponent * icalset_get_next_component(icalset *set)
Definition: icalset.c:408
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)