Diffstat (limited to 'libical/src/libicalss/icalclassify.c') (more/less context) (ignore whitespace changes)
-rw-r--r-- | libical/src/libicalss/icalclassify.c | 792 |
1 files changed, 792 insertions, 0 deletions
diff --git a/libical/src/libicalss/icalclassify.c b/libical/src/libicalss/icalclassify.c new file mode 100644 index 0000000..c029309 --- a/dev/null +++ b/libical/src/libicalss/icalclassify.c | |||
@@ -0,0 +1,792 @@ | |||
1 | /* -*- Mode: C -*- | ||
2 | ====================================================================== | ||
3 | FILE: icalclassify.c | ||
4 | CREATOR: ebusboom 23 aug 2000 | ||
5 | |||
6 | $Id$ | ||
7 | $Locker$ | ||
8 | |||
9 | (C) COPYRIGHT 2000, Eric Busboom, http://www.softwarestudio.org | ||
10 | |||
11 | This program is free software; you can redistribute it and/or modify | ||
12 | it under the terms of either: | ||
13 | |||
14 | The LGPL as published by the Free Software Foundation, version | ||
15 | 2.1, available at: http://www.fsf.org/copyleft/lesser.html | ||
16 | |||
17 | Or: | ||
18 | |||
19 | The Mozilla Public License Version 1.0. You may obtain a copy of | ||
20 | the License at http://www.mozilla.org/MPL/ | ||
21 | |||
22 | |||
23 | ======================================================================*/ | ||
24 | |||
25 | #ifdef HAVE_CONFIG_H | ||
26 | #include "config.h" | ||
27 | #endif | ||
28 | |||
29 | #include "icalerror.h" | ||
30 | #include "ical.h" | ||
31 | #include "icalclassify.h" | ||
32 | #include "icalmemory.h" | ||
33 | #include <ctype.h> /* For tolower() */ | ||
34 | #include <string.h> /* for index() */ | ||
35 | #include <stdlib.h> /* for malloc and free */ | ||
36 | |||
37 | |||
38 | |||
39 | struct icalclassify_parts { | ||
40 | icalcomponent *c; | ||
41 | icalcomponent_kind inner_kind; | ||
42 | icalproperty_method method; | ||
43 | char* organizer; | ||
44 | icalparameter_partstat reply_partstat; | ||
45 | char* reply_attendee; | ||
46 | char* uid; | ||
47 | int sequence; | ||
48 | struct icaltimetype dtstamp; | ||
49 | struct icaltimetype recurrence_id; | ||
50 | }; | ||
51 | |||
52 | |||
53 | char* icalclassify_lowercase(const char* str) | ||
54 | { | ||
55 | char* p = 0; | ||
56 | char* new = icalmemory_strdup(str); | ||
57 | |||
58 | if(str ==0){ | ||
59 | return 0; | ||
60 | } | ||
61 | |||
62 | for(p = new; *p!=0; p++){ | ||
63 | *p = tolower(*p); | ||
64 | } | ||
65 | |||
66 | return new; | ||
67 | } | ||
68 | |||
69 | /* Return a set of components that intersect in time with comp. For | ||
70 | component X and Y to intersect: | ||
71 | X.DTSTART < Y.DTEND && X.DTEND > Y.DTSTART | ||
72 | */ | ||
73 | |||
74 | |||
75 | icalcomponent* icalclassify_find_overlaps(icalset* set, icalcomponent* comp) | ||
76 | { | ||
77 | icalcomponent *return_set; | ||
78 | icalcomponent *c; | ||
79 | struct icaltime_span span,compspan; | ||
80 | |||
81 | icalerror_clear_errno(); | ||
82 | compspan = icalcomponent_get_span(comp); | ||
83 | |||
84 | if(icalerrno != ICAL_NO_ERROR){ | ||
85 | return 0; | ||
86 | } | ||
87 | |||
88 | |||
89 | return_set = icalcomponent_new(ICAL_XROOT_COMPONENT); | ||
90 | |||
91 | for(c = icalset_get_first_component(set); | ||
92 | c != 0; | ||
93 | c = icalset_get_next_component(set)){ | ||
94 | |||
95 | icalerror_clear_errno(); | ||
96 | |||
97 | span = icalcomponent_get_span(c); | ||
98 | |||
99 | if(icalerrno != ICAL_NO_ERROR){ | ||
100 | continue; | ||
101 | } | ||
102 | |||
103 | if (compspan.start < span.end && | ||
104 | compspan.end > span.start){ | ||
105 | |||
106 | icalcomponent *clone = icalcomponent_new_clone(c); | ||
107 | |||
108 | icalcomponent_add_component(return_set,clone); | ||
109 | } | ||
110 | } | ||
111 | |||
112 | if(icalcomponent_count_components(return_set,ICAL_ANY_COMPONENT) !=0){ | ||
113 | return return_set; | ||
114 | } else { | ||
115 | icalcomponent_free(return_set); | ||
116 | return 0; | ||
117 | } | ||
118 | } | ||
119 | |||
120 | |||
121 | |||
122 | icalproperty* icalclassify_find_attendee(icalcomponent *c, | ||
123 | const char* attendee) | ||
124 | { | ||
125 | icalproperty *p; | ||
126 | icalcomponent* inner; | ||
127 | char* lattendee; | ||
128 | char* upn; | ||
129 | |||
130 | if(attendee == 0){ | ||
131 | return 0; | ||
132 | } | ||
133 | |||
134 | lattendee = icalclassify_lowercase(attendee); | ||
135 | upn = strchr(lattendee,':'); | ||
136 | |||
137 | if (upn== 0){ | ||
138 | upn = lattendee; | ||
139 | } else { | ||
140 | upn++; /* skip the ";"*/ | ||
141 | } | ||
142 | |||
143 | inner = icalcomponent_get_first_real_component(c); | ||
144 | |||
145 | for(p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY); | ||
146 | p != 0; | ||
147 | p = icalcomponent_get_next_property(inner,ICAL_ATTENDEE_PROPERTY)) | ||
148 | { | ||
149 | const char* this_attendee | ||
150 | = icalclassify_lowercase(icalproperty_get_attendee(p)); | ||
151 | char* this_upn = strchr(this_attendee,':'); | ||
152 | |||
153 | if(this_upn == 0){ | ||
154 | continue; | ||
155 | } else { | ||
156 | this_upn++; | ||
157 | } | ||
158 | |||
159 | if(strcmp(this_upn,upn)==0){ | ||
160 | return p; | ||
161 | } | ||
162 | |||
163 | } | ||
164 | |||
165 | return 0; | ||
166 | |||
167 | } | ||
168 | |||
169 | void icalssutil_free_parts(struct icalclassify_parts *parts) | ||
170 | { | ||
171 | if(parts == 0){ | ||
172 | return; | ||
173 | } | ||
174 | |||
175 | if(parts->organizer != 0){ | ||
176 | free(parts->organizer); | ||
177 | } | ||
178 | |||
179 | if(parts->uid != 0){ | ||
180 | free(parts->uid); | ||
181 | } | ||
182 | |||
183 | if(parts->reply_attendee){ | ||
184 | free(parts->reply_attendee); | ||
185 | } | ||
186 | } | ||
187 | |||
188 | void icalssutil_get_parts(icalcomponent* c, | ||
189 | struct icalclassify_parts* parts) | ||
190 | { | ||
191 | icalproperty *p; | ||
192 | icalcomponent *inner; | ||
193 | |||
194 | memset(parts,0,sizeof(struct icalclassify_parts)); | ||
195 | |||
196 | parts->method = ICAL_METHOD_NONE; | ||
197 | parts->sequence = 0; | ||
198 | parts->reply_partstat = ICAL_PARTSTAT_NONE; | ||
199 | |||
200 | if(c == 0){ | ||
201 | return; | ||
202 | } | ||
203 | |||
204 | parts->c = c; | ||
205 | |||
206 | p = icalcomponent_get_first_property(c,ICAL_METHOD_PROPERTY); | ||
207 | if(p!=0){ | ||
208 | parts->method = icalproperty_get_method(p); | ||
209 | } | ||
210 | |||
211 | inner = icalcomponent_get_first_real_component(c); | ||
212 | |||
213 | parts->inner_kind = icalcomponent_isa(inner); | ||
214 | |||
215 | p = icalcomponent_get_first_property(inner,ICAL_ORGANIZER_PROPERTY); | ||
216 | if(p!=0){ | ||
217 | parts->organizer = strdup(icalproperty_get_organizer(p)); | ||
218 | } | ||
219 | |||
220 | p = icalcomponent_get_first_property(inner,ICAL_SEQUENCE_PROPERTY); | ||
221 | if(p!=0){ | ||
222 | parts->sequence = icalproperty_get_sequence(p); | ||
223 | } | ||
224 | |||
225 | p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); | ||
226 | if(p!=0){ | ||
227 | parts->uid = strdup(icalproperty_get_uid(p)); | ||
228 | } | ||
229 | |||
230 | p = icalcomponent_get_first_property(inner,ICAL_RECURRENCEID_PROPERTY); | ||
231 | if(p!=0){ | ||
232 | parts->recurrence_id = icalproperty_get_recurrenceid(p); | ||
233 | } | ||
234 | |||
235 | p = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); | ||
236 | if(p!=0){ | ||
237 | parts->dtstamp = icalproperty_get_dtstamp(p); | ||
238 | } | ||
239 | |||
240 | if(parts->method==ICAL_METHOD_REPLY){ | ||
241 | icalparameter *param; | ||
242 | p = icalcomponent_get_first_property(inner,ICAL_ATTENDEE_PROPERTY); | ||
243 | |||
244 | if(p!=0){ | ||
245 | |||
246 | param = icalproperty_get_first_parameter(p,ICAL_PARTSTAT_PARAMETER); | ||
247 | |||
248 | if(param != 0){ | ||
249 | parts->reply_partstat = | ||
250 | icalparameter_get_partstat(param); | ||
251 | } | ||
252 | |||
253 | parts->reply_attendee = strdup(icalproperty_get_attendee(p)); | ||
254 | } | ||
255 | |||
256 | } | ||
257 | |||
258 | |||
259 | } | ||
260 | |||
261 | |||
262 | int icalssutil_is_rescheduled(icalcomponent* a,icalcomponent* b) | ||
263 | { | ||
264 | icalproperty *p1,*p2; | ||
265 | icalcomponent *i1,*i2; | ||
266 | int i; | ||
267 | |||
268 | icalproperty_kind kind_array[] = { | ||
269 | ICAL_DTSTART_PROPERTY, | ||
270 | ICAL_DTEND_PROPERTY, | ||
271 | ICAL_DURATION_PROPERTY, | ||
272 | ICAL_DUE_PROPERTY, | ||
273 | ICAL_RRULE_PROPERTY, | ||
274 | ICAL_RDATE_PROPERTY, | ||
275 | ICAL_EXRULE_PROPERTY, | ||
276 | ICAL_EXDATE_PROPERTY, | ||
277 | ICAL_NO_PROPERTY | ||
278 | }; | ||
279 | |||
280 | i1 = icalcomponent_get_first_real_component(a); | ||
281 | i2 = icalcomponent_get_first_real_component(b); | ||
282 | |||
283 | for(i =0; kind_array[i] != ICAL_NO_PROPERTY; i++){ | ||
284 | p1 = icalcomponent_get_first_property(i1,kind_array[i]); | ||
285 | p2 = icalcomponent_get_first_property(i2,kind_array[i]); | ||
286 | |||
287 | if( (p1!=0)^(p1!=0) ){ | ||
288 | /* Return true if the property exists in one component and not | ||
289 | the other */ | ||
290 | return 1; | ||
291 | } | ||
292 | |||
293 | if(p1 && strcmp(icalproperty_as_ical_string(p1), | ||
294 | icalproperty_as_ical_string(p2)) != 0){ | ||
295 | return 1; | ||
296 | } | ||
297 | } | ||
298 | |||
299 | return 0; | ||
300 | |||
301 | } | ||
302 | |||
303 | #define icalclassify_pre \ | ||
304 | int rtrn =0; | ||
305 | |||
306 | #define icalclassify_post \ | ||
307 | return rtrn; | ||
308 | |||
309 | |||
310 | int icalclassify_publish_new(struct icalclassify_parts *comp, | ||
311 | struct icalclassify_parts *match, | ||
312 | const char* user) | ||
313 | { | ||
314 | icalclassify_pre; | ||
315 | |||
316 | if(comp->method == ICAL_METHOD_PUBLISH && | ||
317 | match == 0 && comp->inner_kind != ICAL_VFREEBUSY_COMPONENT){ | ||
318 | rtrn = 1; | ||
319 | } | ||
320 | |||
321 | icalclassify_post; | ||
322 | |||
323 | } | ||
324 | |||
325 | int icalclassify_publish_update(struct icalclassify_parts *comp, | ||
326 | struct icalclassify_parts *match, | ||
327 | const char* user) | ||
328 | { | ||
329 | icalclassify_pre; | ||
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 | |||
340 | int icalclassify_publish_freebusy(struct icalclassify_parts *comp, | ||
341 | struct icalclassify_parts *match, | ||
342 | const char* user) | ||
343 | { | ||
344 | icalclassify_pre; | ||
345 | |||
346 | if(comp->method == ICAL_METHOD_PUBLISH && | ||
347 | comp->inner_kind == ICAL_VFREEBUSY_COMPONENT){ | ||
348 | rtrn = 1; | ||
349 | } | ||
350 | |||
351 | icalclassify_post; | ||
352 | |||
353 | } | ||
354 | |||
355 | |||
356 | int icalclassify_request_new(struct icalclassify_parts *comp, | ||
357 | struct icalclassify_parts *match, | ||
358 | const char* user) | ||
359 | { | ||
360 | /* Method is REQUEST, and there is no match */ | ||
361 | |||
362 | icalclassify_pre | ||
363 | |||
364 | if(match->c==0 && comp->method == ICAL_METHOD_REQUEST){ | ||
365 | rtrn = 1; | ||
366 | } | ||
367 | |||
368 | icalclassify_post | ||
369 | |||
370 | } | ||
371 | |||
372 | int icalclassify_request_update( | ||
373 | struct icalclassify_parts *comp, | ||
374 | struct icalclassify_parts *match, | ||
375 | const char* user) | ||
376 | { | ||
377 | /* REQUEST method, Higher SEQUENCE than match, and all | ||
378 | time-related properties are unchanged */ | ||
379 | |||
380 | icalclassify_pre | ||
381 | |||
382 | if (match != 0 && | ||
383 | comp->sequence >= match->sequence && | ||
384 | !icalssutil_is_rescheduled(comp->c,match->c)){ | ||
385 | rtrn = 1; | ||
386 | } | ||
387 | |||
388 | icalclassify_post | ||
389 | |||
390 | } | ||
391 | |||
392 | int icalclassify_request_reschedule( | ||
393 | struct icalclassify_parts *comp, | ||
394 | struct icalclassify_parts *match, | ||
395 | const char* user) | ||
396 | { | ||
397 | /* REQUEST method, Higher SEQUENCE than match, and one or more | ||
398 | time-related properties are changed */ | ||
399 | icalclassify_pre | ||
400 | |||
401 | if (match->c != 0 && | ||
402 | comp->sequence > match->sequence && | ||
403 | icalssutil_is_rescheduled(comp->c,match->c)){ | ||
404 | rtrn = 1; | ||
405 | } | ||
406 | |||
407 | icalclassify_post | ||
408 | |||
409 | } | ||
410 | |||
411 | int icalclassify_request_delegate( | ||
412 | struct icalclassify_parts *comp, | ||
413 | struct icalclassify_parts *match, | ||
414 | const char* user) | ||
415 | { | ||
416 | icalproperty* attendee; | ||
417 | icalparameter* param; | ||
418 | icalclassify_pre; | ||
419 | |||
420 | attendee = icalclassify_find_attendee(comp->c,user); | ||
421 | |||
422 | if(attendee == 0){ | ||
423 | return 0; | ||
424 | } | ||
425 | |||
426 | param = icalproperty_get_first_parameter(attendee,ICAL_DELEGATEDFROM_PARAMETER); | ||
427 | |||
428 | if (param != 0){ | ||
429 | rtrn = 1; | ||
430 | } | ||
431 | |||
432 | icalclassify_post | ||
433 | |||
434 | } | ||
435 | |||
436 | int icalclassify_request_new_organizer( | ||
437 | struct icalclassify_parts *comp, | ||
438 | struct icalclassify_parts *match, | ||
439 | const char* user) | ||
440 | { | ||
441 | /* Organizer has changed between match and component */ | ||
442 | icalclassify_pre | ||
443 | icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); | ||
444 | icalclassify_post | ||
445 | |||
446 | } | ||
447 | |||
448 | int icalclassify_request_status( | ||
449 | struct icalclassify_parts *comp, | ||
450 | struct icalclassify_parts *match, | ||
451 | const char* user) | ||
452 | { | ||
453 | icalclassify_pre | ||
454 | icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); | ||
455 | icalclassify_post | ||
456 | } | ||
457 | |||
458 | int icalclassify_request_forward( | ||
459 | struct icalclassify_parts *comp, | ||
460 | struct icalclassify_parts *match, | ||
461 | const char* user) | ||
462 | { | ||
463 | icalclassify_pre | ||
464 | icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); | ||
465 | icalclassify_post | ||
466 | } | ||
467 | |||
468 | int icalclassify_request_freebusy( | ||
469 | struct icalclassify_parts *comp, | ||
470 | struct icalclassify_parts *match, | ||
471 | const char* user) | ||
472 | { | ||
473 | icalclassify_pre | ||
474 | icalerror_set_errno(ICAL_UNIMPLEMENTED_ERROR); | ||
475 | icalclassify_post | ||
476 | } | ||
477 | |||
478 | int icalclassify_reply_accept( | ||
479 | struct icalclassify_parts *comp, | ||
480 | struct icalclassify_parts *match, | ||
481 | const char* user) | ||
482 | { | ||
483 | icalproperty* attendee; | ||
484 | icalclassify_pre; | ||
485 | |||
486 | attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); | ||
487 | |||
488 | if(attendee != 0&& | ||
489 | comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED){ | ||
490 | rtrn = 1; | ||
491 | } | ||
492 | |||
493 | icalclassify_post | ||
494 | } | ||
495 | int icalclassify_reply_decline( | ||
496 | struct icalclassify_parts *comp, | ||
497 | struct icalclassify_parts *match, | ||
498 | const char* user) | ||
499 | { | ||
500 | icalproperty* attendee; | ||
501 | icalclassify_pre; | ||
502 | |||
503 | attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); | ||
504 | |||
505 | |||
506 | if( attendee != 0 && | ||
507 | comp->reply_partstat == ICAL_PARTSTAT_DECLINED){ | ||
508 | rtrn = 1; | ||
509 | } | ||
510 | icalclassify_post | ||
511 | } | ||
512 | int icalclassify_reply_delegate( | ||
513 | struct icalclassify_parts *comp, | ||
514 | struct icalclassify_parts *match, | ||
515 | const char* user) | ||
516 | { | ||
517 | icalproperty* attendee; | ||
518 | icalclassify_pre; | ||
519 | |||
520 | attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); | ||
521 | |||
522 | if( attendee != 0 && | ||
523 | comp->reply_partstat == ICAL_PARTSTAT_DELEGATED){ | ||
524 | rtrn = 1; | ||
525 | } | ||
526 | icalclassify_post | ||
527 | } | ||
528 | int icalclassify_reply_crasher_accept( | ||
529 | struct icalclassify_parts *comp, | ||
530 | struct icalclassify_parts *match, | ||
531 | const char* user) | ||
532 | { | ||
533 | icalproperty* attendee; | ||
534 | icalclassify_pre; | ||
535 | |||
536 | attendee= icalclassify_find_attendee(match->c,comp->reply_attendee); | ||
537 | |||
538 | if(attendee == 0 && | ||
539 | comp->reply_partstat == ICAL_PARTSTAT_ACCEPTED){ | ||
540 | rtrn = 1; | ||
541 | } | ||
542 | icalclassify_post | ||
543 | } | ||
544 | int icalclassify_reply_crasher_decline( | ||
545 | struct icalclassify_parts *comp, | ||
546 | struct icalclassify_parts *match, | ||
547 | const char* user) | ||
548 | { | ||
549 | icalparameter_partstat partstat; | ||
550 | icalproperty* attendee; | ||
551 | icalclassify_pre; | ||
552 | |||
553 | |||
554 | attendee = icalclassify_find_attendee(match->c,comp->reply_attendee); | ||
555 | |||
556 | if(attendee == 0 && | ||
557 | comp->reply_partstat == ICAL_PARTSTAT_DECLINED){ | ||
558 | rtrn = 1; | ||
559 | } | ||
560 | icalclassify_post | ||
561 | } | ||
562 | int icalclassify_add_instance( | ||
563 | struct icalclassify_parts *comp, | ||
564 | struct icalclassify_parts *match, | ||
565 | const char* user) | ||
566 | { | ||
567 | icalclassify_pre | ||
568 | if(comp->method == ICAL_METHOD_ADD){ | ||
569 | rtrn = 1; | ||
570 | } | ||
571 | icalclassify_post | ||
572 | } | ||
573 | int icalclassify_cancel_event( | ||
574 | struct icalclassify_parts *comp, | ||
575 | struct icalclassify_parts *match, | ||
576 | const char* user) | ||
577 | { | ||
578 | icalclassify_pre | ||
579 | if(comp->method == ICAL_METHOD_CANCEL){ | ||
580 | rtrn = 1; | ||
581 | } | ||
582 | icalclassify_post | ||
583 | } | ||
584 | int icalclassify_cancel_instance( | ||
585 | struct icalclassify_parts *comp, | ||
586 | struct icalclassify_parts *match, | ||
587 | const char* user) | ||
588 | { | ||
589 | icalclassify_pre | ||
590 | if(comp->method == ICAL_METHOD_CANCEL){ | ||
591 | rtrn = 1; | ||
592 | } | ||
593 | icalclassify_post | ||
594 | } | ||
595 | int icalclassify_cancel_all( | ||
596 | struct icalclassify_parts *comp, | ||
597 | struct icalclassify_parts *match, | ||
598 | const char* user) | ||
599 | { | ||
600 | icalclassify_pre | ||
601 | if(comp->method == ICAL_METHOD_CANCEL){ | ||
602 | rtrn = 1; | ||
603 | } | ||
604 | icalclassify_post | ||
605 | } | ||
606 | int icalclassify_refesh( | ||
607 | struct icalclassify_parts *comp, | ||
608 | struct icalclassify_parts *match, | ||
609 | const char* user) | ||
610 | { | ||
611 | icalclassify_pre | ||
612 | if(comp->method == ICAL_METHOD_REFRESH){ | ||
613 | rtrn = 1; | ||
614 | } | ||
615 | icalclassify_post | ||
616 | } | ||
617 | int icalclassify_counter( | ||
618 | struct icalclassify_parts *comp, | ||
619 | struct icalclassify_parts *match, | ||
620 | const char* user) | ||
621 | { | ||
622 | icalclassify_pre | ||
623 | if(comp->method == ICAL_METHOD_COUNTER){ | ||
624 | rtrn = 1; | ||
625 | } | ||
626 | icalclassify_post | ||
627 | } | ||
628 | int icalclassify_delinecounter( | ||
629 | struct icalclassify_parts *comp, | ||
630 | struct icalclassify_parts *match, | ||
631 | const char* user) | ||
632 | { | ||
633 | icalclassify_pre | ||
634 | |||
635 | if(comp->method == ICAL_METHOD_DECLINECOUNTER){ | ||
636 | rtrn = 1; | ||
637 | } | ||
638 | |||
639 | icalclassify_post | ||
640 | } | ||
641 | |||
642 | struct icalclassify_map { | ||
643 | icalproperty_method method; | ||
644 | int (*fn)(struct icalclassify_parts *comp,struct icalclassify_parts *match, const char* user); | ||
645 | ical_class class; | ||
646 | } icalclassify_map[] = | ||
647 | { {ICAL_METHOD_PUBLISH,icalclassify_publish_new,ICAL_PUBLISH_NEW_CLASS}, | ||
648 | {ICAL_METHOD_PUBLISH,icalclassify_publish_update,ICAL_PUBLISH_UPDATE_CLASS}, | ||
649 | {ICAL_METHOD_PUBLISH,icalclassify_publish_freebusy,ICAL_PUBLISH_FREEBUSY_CLASS}, | ||
650 | {ICAL_METHOD_REQUEST,icalclassify_request_delegate,ICAL_REQUEST_DELEGATE_CLASS}, | ||
651 | {ICAL_METHOD_REQUEST,icalclassify_request_new,ICAL_REQUEST_NEW_CLASS}, | ||
652 | {ICAL_METHOD_REQUEST,icalclassify_request_update,ICAL_REQUEST_UPDATE_CLASS}, | ||
653 | {ICAL_METHOD_REQUEST,icalclassify_request_reschedule,ICAL_REQUEST_RESCHEDULE_CLASS}, | ||
654 | |||
655 | {ICAL_METHOD_REQUEST,icalclassify_request_new_organizer,ICAL_REQUEST_NEW_ORGANIZER_CLASS}, | ||
656 | {ICAL_METHOD_REQUEST,icalclassify_request_forward,ICAL_REQUEST_FORWARD_CLASS}, | ||
657 | {ICAL_METHOD_REQUEST,icalclassify_request_status,ICAL_REQUEST_STATUS_CLASS}, | ||
658 | {ICAL_METHOD_REQUEST,icalclassify_request_freebusy,ICAL_REQUEST_FREEBUSY_CLASS}, | ||
659 | |||
660 | {ICAL_METHOD_REPLY,icalclassify_reply_accept,ICAL_REPLY_ACCEPT_CLASS}, | ||
661 | {ICAL_METHOD_REPLY,icalclassify_reply_decline,ICAL_REPLY_DECLINE_CLASS}, | ||
662 | {ICAL_METHOD_REPLY,icalclassify_reply_delegate,ICAL_REPLY_DELEGATE_CLASS}, | ||
663 | {ICAL_METHOD_REPLY,icalclassify_reply_crasher_accept,ICAL_REPLY_CRASHER_ACCEPT_CLASS}, | ||
664 | {ICAL_METHOD_REPLY,icalclassify_reply_crasher_decline,ICAL_REPLY_CRASHER_DECLINE_CLASS}, | ||
665 | |||
666 | {ICAL_METHOD_ADD,icalclassify_add_instance,ICAL_ADD_INSTANCE_CLASS}, | ||
667 | |||
668 | {ICAL_METHOD_CANCEL,icalclassify_cancel_event,ICAL_CANCEL_EVENT_CLASS}, | ||
669 | {ICAL_METHOD_CANCEL,icalclassify_cancel_instance,ICAL_CANCEL_INSTANCE_CLASS}, | ||
670 | {ICAL_METHOD_CANCEL,icalclassify_cancel_all,ICAL_CANCEL_ALL_CLASS}, | ||
671 | |||
672 | {ICAL_METHOD_REFRESH,icalclassify_refesh,ICAL_REFRESH_CLASS}, | ||
673 | {ICAL_METHOD_COUNTER,icalclassify_counter,ICAL_COUNTER_CLASS}, | ||
674 | {ICAL_METHOD_DECLINECOUNTER,icalclassify_delinecounter,ICAL_DECLINECOUNTER_CLASS}, | ||
675 | {ICAL_METHOD_NONE,0,ICAL_NO_CLASS} | ||
676 | }; | ||
677 | |||
678 | |||
679 | ical_class icalclassify(icalcomponent* c,icalcomponent* match, | ||
680 | const char* user) | ||
681 | { | ||
682 | icalcomponent *inner; | ||
683 | icalproperty *p; | ||
684 | icalproperty_method method; | ||
685 | ical_class class = ICAL_UNKNOWN_CLASS; | ||
686 | |||
687 | int i; | ||
688 | |||
689 | struct icalclassify_parts comp_parts; | ||
690 | struct icalclassify_parts match_parts; | ||
691 | |||
692 | inner = icalcomponent_get_first_real_component(c); | ||
693 | |||
694 | if (inner == 0) { | ||
695 | return ICAL_NO_CLASS; | ||
696 | } | ||
697 | |||
698 | icalssutil_get_parts(c,&comp_parts); | ||
699 | icalssutil_get_parts(match,&match_parts); | ||
700 | |||
701 | /* Determine if the incoming component is obsoleted by the match */ | ||
702 | if(match != 0 && ( | ||
703 | comp_parts.method == ICAL_METHOD_REQUEST | ||
704 | )){ | ||
705 | assert ( ! ((comp_parts.dtstamp.is_utc==1)^ | ||
706 | (match_parts.dtstamp.is_utc==1))); | ||
707 | |||
708 | if( comp_parts.sequence<match_parts.sequence && | ||
709 | icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)>0) | ||
710 | { | ||
711 | /* comp has a smaller sequence and a later DTSTAMP */ | ||
712 | return ICAL_MISSEQUENCED_CLASS; | ||
713 | } | ||
714 | |||
715 | if( (comp_parts.sequence<match_parts.sequence ) | ||
716 | /*&&icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)<=0*/ | ||
717 | || | ||
718 | ( comp_parts.sequence == match_parts.sequence && | ||
719 | icaltime_compare(comp_parts.dtstamp,match_parts.dtstamp)<=0)){ | ||
720 | |||
721 | return ICAL_OBSOLETE_CLASS; | ||
722 | } | ||
723 | |||
724 | } | ||
725 | |||
726 | p = icalcomponent_get_first_property(c,ICAL_METHOD_PROPERTY); | ||
727 | if (p == 0) { | ||
728 | return ICAL_UNKNOWN_CLASS; | ||
729 | } | ||
730 | method = icalproperty_get_method(p); | ||
731 | |||
732 | for (i =0; icalclassify_map[i].method != ICAL_METHOD_NONE; i++){ | ||
733 | if(icalclassify_map[i].method == method){ | ||
734 | if( (*(icalclassify_map[i].fn))(&comp_parts,&match_parts,user)==1){ | ||
735 | class = icalclassify_map[i].class; | ||
736 | break; | ||
737 | } | ||
738 | } | ||
739 | } | ||
740 | |||
741 | icalssutil_free_parts(&comp_parts); | ||
742 | icalssutil_free_parts(&match_parts); | ||
743 | |||
744 | return class; | ||
745 | |||
746 | } | ||
747 | |||
748 | struct class_map { | ||
749 | ical_class class; | ||
750 | char *str; | ||
751 | } class_map[] = { | ||
752 | {ICAL_NO_CLASS,"No class"}, | ||
753 | {ICAL_PUBLISH_NEW_CLASS,"New Publish"}, | ||
754 | {ICAL_PUBLISH_UPDATE_CLASS,"Publish Update"}, | ||
755 | {ICAL_PUBLISH_FREEBUSY_CLASS,"Publish freebusy"}, | ||
756 | {ICAL_REQUEST_NEW_CLASS,"New request"}, | ||
757 | {ICAL_REQUEST_UPDATE_CLASS,"Update"}, | ||
758 | {ICAL_REQUEST_RESCHEDULE_CLASS,"Reschedule"}, | ||
759 | {ICAL_REQUEST_DELEGATE_CLASS,"Delegate request"}, | ||
760 | {ICAL_REQUEST_NEW_ORGANIZER_CLASS,"New Organizer"}, | ||
761 | {ICAL_REQUEST_FORWARD_CLASS,"Forward"}, | ||
762 | {ICAL_REQUEST_STATUS_CLASS,"Status request"}, | ||
763 | {ICAL_REPLY_ACCEPT_CLASS,"Accept reply"}, | ||
764 | {ICAL_REPLY_DECLINE_CLASS,"Decline reply"}, | ||
765 | {ICAL_REPLY_DELEGATE_CLASS,"Delegation reply"}, | ||
766 | {ICAL_REPLY_CRASHER_ACCEPT_CLASS,"Crasher's accept reply"}, | ||
767 | {ICAL_REPLY_CRASHER_DECLINE_CLASS,"Crasher's decline reply"}, | ||
768 | {ICAL_ADD_INSTANCE_CLASS,"Add instance"}, | ||
769 | {ICAL_CANCEL_EVENT_CLASS,"Cancel event"}, | ||
770 | {ICAL_CANCEL_INSTANCE_CLASS,"Cancel instance"}, | ||
771 | {ICAL_CANCEL_ALL_CLASS,"Cancel all instances"}, | ||
772 | {ICAL_REFRESH_CLASS,"Refresh"}, | ||
773 | {ICAL_COUNTER_CLASS,"Counter"}, | ||
774 | {ICAL_DECLINECOUNTER_CLASS,"Decline counter"}, | ||
775 | {ICAL_MALFORMED_CLASS,"Malformed"}, | ||
776 | {ICAL_OBSOLETE_CLASS,"Obsolete"}, | ||
777 | {ICAL_MISSEQUENCED_CLASS,"Missequenced"}, | ||
778 | {ICAL_UNKNOWN_CLASS,"Unknown"} | ||
779 | }; | ||
780 | |||
781 | char* icalclassify_class_to_string(ical_class class) | ||
782 | { | ||
783 | int i; | ||
784 | |||
785 | for (i = 0;class_map[i].class != ICAL_UNKNOWN_CLASS;i++){ | ||
786 | if (class_map[i].class == class){ | ||
787 | return class_map[i].str; | ||
788 | } | ||
789 | } | ||
790 | |||
791 | return "Unknown"; | ||
792 | } | ||