static icalcomponent *icalmessage_get_inner(icalcomponent *comp) { if (icalcomponent_isa(comp) == ICAL_VCALENDAR_COMPONENT) { return icalcomponent_get_first_real_component(comp); } else { return comp; } }
struct icalbdbset_id icalbdbset_get_id(icalcomponent *comp) { icalcomponent *inner; struct icalbdbset_id id; icalproperty *p; inner = icalcomponent_get_first_real_component(comp); p = icalcomponent_get_first_property(inner, ICAL_UID_PROPERTY); assert(p != 0); id.uid = strdup(icalproperty_get_uid(p)); p = icalcomponent_get_first_property(inner, ICAL_SEQUENCE_PROPERTY); if (p == 0) { id.sequence = 0; } else { id.sequence = icalproperty_get_sequence(p); } p = icalcomponent_get_first_property(inner, ICAL_RECURRENCEID_PROPERTY); if (p == 0) { id.recurrence_id = 0; } else { icalvalue *v; v = icalproperty_get_value(p); id.recurrence_id = icalvalue_as_ical_string_r(v); assert(id.recurrence_id != 0); } return id; }
int icalgauge_compare(icalgauge* gauge,icalcomponent* comp) { icalcomponent *inner; int local_pass = 0; int last_clause = 1, this_clause = 1; pvl_elem e; icalcomponent_kind kind; icalproperty *rrule; int compare_recur = 0; icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); if (gauge == 0 || comp == 0) return 0; inner = icalcomponent_get_first_real_component(comp); if(inner == 0){ /* Wally Yau: our component is not always wrapped with * a <VCALENDAR>. It's not an error. * icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); * return 0; */ kind = icalcomponent_isa(comp); if(kind == ICAL_VEVENT_COMPONENT || kind == ICAL_VTODO_COMPONENT || kind == ICAL_VJOURNAL_COMPONENT || kind == ICAL_VQUERY_COMPONENT || kind == ICAL_VAGENDA_COMPONENT){ inner = comp; } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return 0; } inner = comp; } /* Check that this component is one of the FROM types */ local_pass = 0; for(e = pvl_head(gauge->from);e!=0;e=pvl_next(e)){ icalcomponent_kind k = (icalcomponent_kind)pvl_data(e); if(k == icalcomponent_isa(inner)){ local_pass=1; } } if(local_pass == 0){ return 0; } /**** Check each where clause against the component ****/ for(e = pvl_head(gauge->where);e!=0;e=pvl_next(e)){ struct icalgauge_where *w = pvl_data(e); icalcomponent *sub_comp; icalvalue *v; icalproperty *prop; icalvalue_kind vk; if(w->prop == ICAL_NO_PROPERTY || w->value == 0){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } /* First, create a value from the gauge */ vk = icalenum_property_kind_to_value_kind(w->prop); if(vk == ICAL_NO_VALUE){ icalerror_set_errno(ICAL_INTERNAL_ERROR); return 0; } if (w->compare == ICALGAUGECOMPARE_ISNULL || w->compare == ICALGAUGECOMPARE_ISNOTNULL) v = icalvalue_new(vk); else v = icalvalue_new_from_string(vk,w->value); if (v == 0){ /* Keep error set by icalvalue_from-string*/ return 0; } /* Now find the corresponding property in the component, descending into a sub-component if necessary */ if(w->comp == ICAL_NO_COMPONENT){ sub_comp = inner; } else { sub_comp = icalcomponent_get_first_component(inner,w->comp); if(sub_comp == 0){ return 0; } } /* check if it is a recurring */ rrule = icalcomponent_get_first_property(sub_comp,ICAL_RRULE_PROPERTY); if (gauge->expand && rrule) { if (w->prop == ICAL_DTSTART_PROPERTY || w->prop == ICAL_DTEND_PROPERTY || w->prop == ICAL_DUE_PROPERTY){ /** needs to use recurrence-id to do comparison */ compare_recur = 1; } } this_clause = 0; local_pass = (w->compare == ICALGAUGECOMPARE_ISNULL) ? 1 : 0; for(prop = icalcomponent_get_first_property(sub_comp,w->prop); prop != 0; prop = icalcomponent_get_next_property(sub_comp,w->prop)){ icalvalue* prop_value; icalgaugecompare relation; if (w->compare == ICALGAUGECOMPARE_ISNULL) { local_pass = 0; break; } if (w->compare == ICALGAUGECOMPARE_ISNOTNULL) { local_pass = 1; break; } if (compare_recur) { icalproperty *p = icalcomponent_get_first_property(sub_comp, ICAL_RECURRENCEID_PROPERTY); prop_value = icalproperty_get_value(p); } else /* prop value from this component */ prop_value = icalproperty_get_value(prop); relation = (icalgaugecompare)icalvalue_compare(prop_value,v); if (relation == w->compare){ local_pass++; } else if (w->compare == ICALGAUGECOMPARE_LESSEQUAL && ( relation == ICALGAUGECOMPARE_LESS || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_GREATEREQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_EQUAL)) { local_pass++; } else if (w->compare == ICALGAUGECOMPARE_NOTEQUAL && ( relation == ICALGAUGECOMPARE_GREATER || relation == ICALGAUGECOMPARE_LESS)) { local_pass++; } else { local_pass = 0; } } this_clause = local_pass > 0 ? 1 : 0; /* Now look at the logic operator for this clause to see how the value should be merge with the previous clause */ if(w->logic == ICALGAUGELOGIC_AND){ last_clause = this_clause && last_clause; } else if(w->logic == ICALGAUGELOGIC_OR) { last_clause = this_clause || last_clause; } else { last_clause = this_clause; } icalvalue_free(v); }/**** check next one in where clause ****/ return last_clause; }
int main(int argc, char *argv[]) { icalcomponent *c, *next_c = NULL; int i = 0; int dont_remove; icalfileset_options options = { O_RDONLY, 0644, 0, NULL }; icalset *f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-incoming.ics", &options); icalset *trash = icalset_new_file("trash.ics"); icalset *cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/process-calendar.ics", &options); icalset *out = icalset_new_file("outgoing.ics"); const char *this_user = "******"; _unused(argc); _unused(argv); assert(f != 0); assert(cal != 0); assert(trash != 0); assert(out != 0); /* Foreach incoming message */ for (c = icalset_get_first_component(f); c != 0; c = next_c) { icalproperty_xlicclass class; icalcomponent *match; icalcomponent *inner; icalcomponent *reply = 0; assert(c != 0); inner = icalcomponent_get_first_real_component(c); i++; reply = 0; dont_remove = 0; if (inner == 0) { printf("Bad component, no inner\n %s\n", icalcomponent_as_ical_string(c)); continue; } /* Find a booked component that is matched to the incoming message, based on the incoming component's UID, SEQUENCE and RECURRENCE-ID */ match = icalset_fetch_match(cal, c); class = icalclassify(c, match, this_user); /* Print out the notes associated with the incoming component and the matched component in the */ { const char *inc_note = 0; const char *match_note = 0; icalproperty *p; for (p = icalcomponent_get_first_property(c, ICAL_X_PROPERTY); p != 0; p = icalcomponent_get_next_property(c, ICAL_X_PROPERTY)) { if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) { inc_note = icalproperty_get_x(p); } } if (match != 0) { for (p = icalcomponent_get_first_property(match, ICAL_X_PROPERTY); p != 0; p = icalcomponent_get_next_property(match, ICAL_X_PROPERTY)) { if (strcmp(icalproperty_get_x_name(p), "X-LIC-NOTE") == 0) { match_note = icalproperty_get_x(p); } } } if (inc_note != 0) { printf("Incoming: %s\n", inc_note); } if (match_note != 0) { printf("Match : %s\n", match_note); } } /* Main processing structure */ switch (class) { case ICAL_XLICCLASS_NONE:{ char temp[1024]; /* Huh? Return an error to sender */ icalrestriction_check(c); icalcomponent_convert_errors(c); snprintf(temp, 1024, "I can't understand the component you sent.\n" "Here is the component you sent, possibly with error messages:\n" "%s", icalcomponent_as_ical_string(c)); reply = icalmessage_new_error_reply(c, this_user, temp, "", ICAL_UNKNOWN_STATUS); break; } case ICAL_XLICCLASS_PUBLISHNEW:{ /* Don't accept published events from anyone but self. If self, fall through to ICAL_XLICCLASS_REQUESTNEW */ } case ICAL_XLICCLASS_REQUESTNEW:{ /* Book the new component if it does not overlap anything. If the time is busy and the start time is an even modulo 4, delegate to [email protected]. If the time is busy and is 1 modulo 4, counterpropose for the first available free time. Otherwise, deline the meeting */ icalcomponent *overlaps = icalclassify_find_overlaps(cal, c); if (overlaps == 0) { /* No overlaps, book the meeting */ /* icalset_add_component(cal,icalcomponent_new_clone(c));*/ /* Return a reply */ reply = icalmessage_new_accept_reply( c, this_user, "I can make it to this meeting"); (void)icalset_add_component(out, reply); } else { /* There was a conflict, so delegate, counterpropose or decline it */ struct icaltimetype dtstart = icalcomponent_get_dtstart(c); if (dtstart.hour % 4 == 0) { /* Delegate the meeting */ reply = icalmessage_new_delegate_reply( c, this_user, "*****@*****.**", "Unfortunately, I have another commitment that conflicts " "with this meeting. I am delegating my attendance to Bob."); (void)icalset_add_component(out, reply); } else if (dtstart.hour % 4 == 1) { /* Counter propose to next available time */ icalcomponent *newc; struct icalperiodtype next_time; icalspanlist *spanl = icalspanlist_new(cal, dtstart, icaltime_null_time()); next_time = icalspanlist_next_free_time(spanl, icalcomponent_get_dtstart(c)); newc = icalcomponent_new_clone(c); icalcomponent_set_dtstart(newc, next_time.start); /* Hack, the duration of the counterproposed meeting may be longer than the free time available */ icalcomponent_set_duration(newc, icalcomponent_get_duration(c)); reply = icalmessage_new_counterpropose_reply( c, newc, this_user, "Unfortunately, I have another commitment that conflicts with " "this meeting. I am proposing a time that works better for me."); (void)icalset_add_component(out, reply); icalspanlist_free(spanl); icalcomponent_free(newc); } else { /* Decline the meeting */ reply = icalmessage_new_decline_reply( c, this_user, "I can't make it to this meeting"); (void)icalset_add_component(out, reply); } } icalcomponent_free(overlaps); break; } case ICAL_XLICCLASS_PUBLISHFREEBUSY:{ /* Store the busy time information in a file named after the sender */ break; } case ICAL_XLICCLASS_PUBLISHUPDATE:{ /* Only accept publish updates from self. If self, fall through to ICAL_XLICCLASS_REQUESTUPDATE */ } case ICAL_XLICCLASS_REQUESTUPDATE:{ /* always accept the changes */ break; } case ICAL_XLICCLASS_REQUESTRESCHEDULE:{ /* Use same rules as REQUEST_NEW */ (void)icalclassify_find_overlaps(cal, c); break; } case ICAL_XLICCLASS_REQUESTDELEGATE:{ break; } case ICAL_XLICCLASS_REQUESTNEWORGANIZER:{ break; } case ICAL_XLICCLASS_REQUESTFORWARD:{ break; } case ICAL_XLICCLASS_REQUESTSTATUS:{ break; } case ICAL_XLICCLASS_REQUESTFREEBUSY:{ break; } case ICAL_XLICCLASS_REPLYACCEPT:{ /* Change the PARTSTAT of the sender */ break; } case ICAL_XLICCLASS_REPLYDECLINE:{ /* Change the PARTSTAT of the sender */ break; } case ICAL_XLICCLASS_REPLYCRASHERACCEPT:{ /* Add the crasher to the ATTENDEE list with the appropriate PARTSTAT */ break; } case ICAL_XLICCLASS_REPLYCRASHERDECLINE:{ /* Add the crasher to the ATTENDEE list with the appropriate PARTSTAT */ break; } case ICAL_XLICCLASS_ADDINSTANCE:{ break; } case ICAL_XLICCLASS_CANCELEVENT:{ /* Remove the component */ break; } case ICAL_XLICCLASS_CANCELINSTANCE:{ break; } case ICAL_XLICCLASS_CANCELALL:{ /* Remove the component */ break; } case ICAL_XLICCLASS_REFRESH:{ /* Resend the latest copy of the request */ break; } case ICAL_XLICCLASS_COUNTER:{ break; } case ICAL_XLICCLASS_DECLINECOUNTER:{ break; } case ICAL_XLICCLASS_MALFORMED:{ /* Send back an error */ break; } case ICAL_XLICCLASS_OBSOLETE:{ printf(" ** Got an obsolete component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_MISSEQUENCED:{ printf(" ** Got a missequenced component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_UNKNOWN:{ printf(" ** Don't know what to do with this component:\n%s", icalcomponent_as_ical_string(c)); /* Send back an error */ break; } case ICAL_XLICCLASS_X: case ICAL_XLICCLASS_REPLYDELEGATE: default:{ } } #if 0 if (reply != 0) { /* Don't send the reply if the RSVP parameter indicates not to */ icalcomponent *reply_inner; icalproperty *attendee; icalparameter *rsvp; reply_inner = icalcomponent_get_first_real_component(reply); attendee = icalcomponent_get_first_property(reply_inner, ICAL_ATTENDEE_PROPERTY); rsvp = icalproperty_get_first_parameter(attendee, ICAL_RSVP_PARAMETER); if (rsvp == 0 || icalparameter_get_rsvp(rsvp) == 1) { icalrestriction_check(reply); send_message(reply, this_user); } icalcomponent_free(reply); } #endif if (reply != 0) { printf("%s\n", icalcomponent_as_ical_string(reply)); } next_c = icalset_get_next_component(f); if (dont_remove == 0) { /*icalset_remove_component(f,c); icalset_add_component(trash,c); */ } } #if 0 for (c = icalset_get_first_component(out); c != 0; c = icalset_get_next_component(out)) { printf("%s", icalcomponent_as_ical_string(c)); } #endif icalset_free(f); icalset_free(trash); icalset_free(cal); icalset_free(out); return 0; }