icalset* icaldirset_new_reader(const char* dir) { icaldirset_options reader_options = icaldirset_options_default; reader_options.flags = O_RDONLY; return icalset_new(ICAL_DIR_SET, dir, &reader_options); }
icalset* icaldirset_new_writer(const char* dir) { icaldirset_options writer_options = icaldirset_options_default; writer_options.flags = O_RDWR|O_CREAT; return icalset_new(ICAL_DIR_SET, dir, &writer_options); }
icalset *icalbdbset_new(const char *database_filename, icalbdbset_subdb_type subdb_type, int dbtype, u_int32_t flag) { icalbdbset_options options = icalbdbset_options_default; options.subdb = subdb_type; options.dbtype = dbtype; options.flag = flag; /* this will in turn call icalbdbset_init */ return icalset_new(ICAL_BDB_SET, database_filename, &options); }
icalerrorenum icaldirset_commit(icalset* set) { icaldirset *dset = (icaldirset*)set; icalset *fileset; icalfileset_options options = icalfileset_options_default; options.cluster = dset->cluster; fileset = icalset_new(ICAL_FILE_SET, icalcluster_key(dset->cluster), &options); fileset->commit(fileset); fileset->free(fileset); return ICAL_NO_ERROR; }
void test_recur_file() { icalset *cin = 0; struct icaltimetype next; icalcomponent *itr; icalproperty *desc, *dtstart, *rrule; struct icalrecurrencetype recur; icalrecur_iterator* ritr; time_t tt; char* file; int num_recurs_found = 0; icalfileset_options options = {O_RDONLY, 0644, 0}; icalerror_set_error_state(ICAL_PARSE_ERROR, ICAL_ERROR_NONFATAL); #ifndef WIN32 signal(SIGALRM,sig_alrm); #endif file = getenv("ICAL_RECUR_FILE"); if (!file) file = TEST_DATADIR "/recur.txt"; #ifndef WIN32 alarm(15); /* to get file lock */ #endif cin = icalset_new(ICAL_FILE_SET, file, &options); #ifndef WIN32 alarm(0); #endif ok("opening file with recurring events", (cin!=NULL)); assert(cin!=NULL); for (itr = icalfileset_get_first_component(cin); itr != 0; itr = icalfileset_get_next_component(cin)){ int badcomp = 0; int expected_events = 0; char msg[128]; struct icaltimetype start = icaltime_null_time(); struct icaltimetype startmin = icaltime_from_timet(1,0); struct icaltimetype endmax = icaltime_null_time(); const char *desc_str = "malformed component"; desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY); dtstart = icalcomponent_get_first_property(itr,ICAL_DTSTART_PROPERTY); rrule = icalcomponent_get_first_property(itr,ICAL_RRULE_PROPERTY); if (desc) { desc_str = icalproperty_get_description(desc); } ok((char*)desc_str, !(desc == 0 || dtstart == 0 || rrule == 0)); if (desc == 0 || dtstart == 0 || rrule == 0) { badcomp = 1; if (VERBOSE) { printf("\n******** Error in input component ********\n"); printf("The following component is malformed:\n %s\n", desc_str); } continue; } if (VERBOSE) { printf("\n\n#### %s\n",desc_str); printf("#### %s\n",icalvalue_as_ical_string(icalproperty_get_value(rrule))); } recur = icalproperty_get_rrule(rrule); start = icalproperty_get_dtstart(dtstart); ritr = icalrecur_iterator_new(recur,start); tt = icaltime_as_timet(start); if (VERBOSE) printf("#### %s\n",ctime(&tt )); icalrecur_iterator_free(ritr); for(ritr = icalrecur_iterator_new(recur,start), next = icalrecur_iterator_next(ritr); !icaltime_is_null_time(next); next = icalrecur_iterator_next(ritr)){ tt = icaltime_as_timet(next); if (VERBOSE) printf(" %s",ctime(&tt )); } icalrecur_iterator_free(ritr); num_recurs_found = 0; expected_events = get_expected_numevents(itr); icalcomponent_foreach_recurrence(itr, startmin, endmax, recur_callback, &num_recurs_found); sprintf(msg," expecting total of %d events", expected_events); int_is(msg, num_recurs_found, expected_events); } icalset_free(cin); }
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; }
icalset* icaldirset_new(const char* dir) { return icalset_new(ICAL_DIR_SET, dir, &icaldirset_options_default); }
void test_classify(void) { icalcomponent *c, *match; int i = 0; int error_count = 0; /* Open up the two storage files, one for the incomming components, one for the calendar */ icalfileset_options options = { O_RDONLY, 0644, 0, NULL }; icalset *incoming = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/incoming.ics", &options); icalset *cal = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/calendar.ics", &options); icalset *f = icalset_new(ICAL_FILE_SET, TEST_DATADIR "/classify.ics", &options); ok("opening file classify.ics", (f != 0)); ok("opening file calendar.ics", (cal != 0)); ok("opening file incoming.ics", (incoming != 0)); /* some basic tests.. */ if (f) { c = icalset_get_first_component(f); match = icalset_get_next_component(f); ok("test two vcalendars for SEQUENCE with icalclassify()", (icalclassify(c, match, "*****@*****.**") == ICAL_XLICCLASS_REQUESTRESCHEDULE)); icalset_free(f); } assert(incoming != 0); assert(cal != 0); /* Iterate through all of the incoming components */ for (c = icalset_get_first_component(incoming); c != 0; c = icalset_get_next_component(incoming)) { icalproperty_xlicclass class; icalcomponent *match = 0; const char *this_uid; const char *this_note = get_note(c); const char *expected_result = get_expect(c); const char *actual_result; char msg[128]; i++; /* Check this component against the restrictions imposed by iTIP. An errors will be inserted as X-LIC-ERROR properties in the component. The Parser will also insert errors if it cannot parse the component */ icalcomponent_check_restrictions(c); /* If there are any errors, print out the component */ error_count = icalcomponent_count_errors(c); snprintf(msg, sizeof(msg), "%s - parsing", this_note); int_is(msg, error_count, 0); if (error_count != 0) { if (VERBOSE) { printf("----- Component has errors ------- \n%s-----------------\n", icalcomponent_as_ical_string(c)); } } /* Use one of the icalcomponent convenience routines to get the UID. This routine will save you from having to use icalcomponent_get_inner(), icalcomponent_get_first_property(), checking the return value, and then calling icalproperty_get_uid. There are several other convenience routines for DTSTART, DTEND, DURATION, SUMMARY, METHOD, and COMMENT */ this_uid = icalcomponent_get_uid(c); if (this_uid != 0) { /* Look in the calendar for a component with the same UID as the incomming component. We should reall also be checking the RECURRENCE-ID. Another way to do this operation is to us icalset_find_match(), which does use the RECURRENCE-ID. */ match = icalset_fetch(cal, this_uid); } /* Classify the incoming component. The third argument is the calid of the user who owns the calendar. In a real program, you would probably switch() on the class. */ class = icalclassify(c, match, "*****@*****.**"); /** eventually test this too.. **/ (void)get_note(match); actual_result = icalproperty_enum_to_string(class); snprintf(msg, sizeof(msg), "expecting %s", expected_result); str_is(msg, expected_result, actual_result); if (VERBOSE) { printf("Test %d\n" "Incoming: %s\n" "Matched: %s\n" "Classification: %s\n\n", i, this_note, get_note(match), icalproperty_enum_to_string(class)); } } icalset_free(incoming); icalset_free(cal); }
icalset* icalset_new_dir(const char* path) { return icalset_new(ICAL_DIR_SET, path, NULL); }
icalset* icalset_new_file(const char* path) { return icalset_new(ICAL_FILE_SET, path, NULL); }