From 5ccacd6a5bbeb2d91aea706f37cc5f96ee3144fb Mon Sep 17 00:00:00 2001 From: Federico Mena Quintero Date: Mon, 11 Dec 2000 22:07:15 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r6917, which included commits to RCS files with non-trunk default branches. svn path=/trunk/; revision=6918 --- libical/examples/access_components.c | 58 ++-- libical/examples/errors.c | 2 +- libical/examples/main.c | 7 +- libical/examples/parse_text.c | 3 +- libical/src/libical/icalmime.c | 86 +++++- libical/src/libical/icalmime.h | 14 +- libical/src/libical/icalrecur.c | 249 +++++++++++++---- libical/src/libical/icalrecur.h | 108 ++++++- libical/src/libical/sspm.c | 482 ++++++++++++++++++++++++++++++-- libical/src/libical/sspm.h | 27 +- libical/src/libicalss/icaldirset.c | 125 +++++---- libical/src/libicalss/icaldirset.h | 20 +- libical/src/libicalss/icalfileset.c | 183 ++++++++++-- libical/src/libicalss/icalfileset.h | 21 +- libical/src/libicalss/icalfilesetimpl.h | 4 + libical/src/libicalss/icalgauge.c | 55 +++- libical/src/libicalss/icalgauge.h | 10 +- libical/src/libicalss/icalset.c | 337 ++++++++++++++++++++-- libical/src/libicalss/icalset.h | 17 +- libical/src/libicalvcal/icalvcal.c | 27 +- libical/src/test/recur.c | 6 +- libical/src/test/testmime.c | 5 +- 22 files changed, 1548 insertions(+), 298 deletions(-) diff --git a/libical/examples/access_components.c b/libical/examples/access_components.c index 6b655b42f7..18fc6a6144 100644 --- a/libical/examples/access_components.c +++ b/libical/examples/access_components.c @@ -9,6 +9,8 @@ #include /* for time() */ #include "icalmemory.h" +void do_something(icalcomponent *c); + /* Creating iCal Components There are two ways to create new component in libical. You can @@ -59,14 +61,9 @@ icalcomponent* create_new_component() icalcomponent_add_property( calendar, - icalproperty_new_version(strdup("2.0")) + icalproperty_new_version("2.0") ); - /* Note the use of strdup() in the previous and next call. All - properties constructors for properties with value types of - TEXT will take control of the string you pass into them. Since - the string '2.0' is a static string, we need to duplicate it in - new memory before giving it to the property */ /* Here is the short version of the memory rules: @@ -88,7 +85,7 @@ icalcomponent* create_new_component() icalcomponent_add_property( calendar, - icalproperty_new_prodid(strdup("-//RDU Software//NONSGML HandCal//EN")) + icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN") ); /* Add an event */ @@ -105,11 +102,11 @@ icalcomponent* create_new_component() icalcomponent_add_property( event, - icalproperty_new_uid(strdup("guid-1.host1.com")) + icalproperty_new_uid("guid-1.host1.com") ); /* add a property that has parameters */ - property = icalproperty_new_organizer(strdup("mailto:mrbig@host.com")); + property = icalproperty_new_organizer("mailto:mrbig@host.com"); icalproperty_add_parameter( property, @@ -123,7 +120,7 @@ icalcomponent* create_new_component() operation is the same as adding a property to a component */ /* add another property that has parameters */ - property = icalproperty_new_attendee(strdup("mailto:employee-A@host.com")); + property = icalproperty_new_attendee("mailto:employee-A@host.com"); icalproperty_add_parameter( property, @@ -147,17 +144,17 @@ icalcomponent* create_new_component() icalcomponent_add_property( event, - icalproperty_new_description(strdup("Project XYZ Review Meeting")) + icalproperty_new_description("Project XYZ Review Meeting") ); icalcomponent_add_property( event, - icalproperty_new_categories(strdup("MEETING")) + icalproperty_new_categories("MEETING") ); icalcomponent_add_property( event, - icalproperty_new_class(strdup("PUBLIC")) + icalproperty_new_class("PUBLIC") ); icalcomponent_add_property( @@ -167,14 +164,14 @@ icalcomponent* create_new_component() icalcomponent_add_property( event, - icalproperty_new_summary(strdup("XYZ Project Review")) + icalproperty_new_summary("XYZ Project Review") ); property = icalproperty_new_dtstart(atime); icalproperty_add_parameter( property, - icalparameter_new_tzid(strdup("US-Eastern")) + icalparameter_new_tzid("US-Eastern") ); icalcomponent_add_property(event,property); @@ -184,14 +181,14 @@ icalcomponent* create_new_component() icalproperty_add_parameter( property, - icalparameter_new_tzid(strdup("US-Eastern")) + icalparameter_new_tzid("US-Eastern") ); icalcomponent_add_property(event,property); icalcomponent_add_property( event, - icalproperty_new_location(strdup("1CP Conference Room 4350")) + icalproperty_new_location("1CP Conference Room 4350") ); icalcomponent_add_component(calendar,event); @@ -224,44 +221,41 @@ icalcomponent* create_new_component_with_va_args() calendar = icalcomponent_vanew( ICAL_VCALENDAR_COMPONENT, - icalproperty_new_version(strdup("2.0")), - icalproperty_new_prodid(strdup("-//RDU Software//NONSGML HandCal//EN")), + icalproperty_new_version("2.0"), + icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"), icalcomponent_vanew( ICAL_VEVENT_COMPONENT, icalproperty_new_dtstamp(atime), - icalproperty_new_uid(strdup("guid-1.host1.com")), + icalproperty_new_uid("guid-1.host1.com"), icalproperty_vanew_organizer( - strdup("mailto:mrbig@host.com"), + "mailto:mrbig@host.com", icalparameter_new_role(ICAL_ROLE_CHAIR), 0 ), icalproperty_vanew_attendee( - strdup("mailto:employee-A@host.com"), + "mailto:employee-A@host.com", icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT), icalparameter_new_rsvp(1), icalparameter_new_cutype(ICAL_CUTYPE_GROUP), 0 ), - icalproperty_new_description(strdup("Project XYZ Review Meeting")), - - /* Again, note the use of strdup to give libical - ownership of a static string. */ + icalproperty_new_description("Project XYZ Review Meeting"), - icalproperty_new_categories(strdup("MEETING")), - icalproperty_new_class(strdup("PUBLIC")), + icalproperty_new_categories("MEETING"), + icalproperty_new_class("PUBLIC"), icalproperty_new_created(atime), - icalproperty_new_summary(strdup("XYZ Project Review")), + icalproperty_new_summary("XYZ Project Review"), icalproperty_vanew_dtstart( atime, - icalparameter_new_tzid(strdup("US-Eastern")), + icalparameter_new_tzid("US-Eastern"), 0 ), icalproperty_vanew_dtend( atime, - icalparameter_new_tzid(strdup("US-Eastern")), + icalparameter_new_tzid("US-Eastern"), 0 ), - icalproperty_new_location(strdup("1CP Conference Room 4350")), + icalproperty_new_location("1CP Conference Room 4350"), 0 ), 0 diff --git a/libical/examples/errors.c b/libical/examples/errors.c index 071a2de816..86d963bd75 100644 --- a/libical/examples/errors.c +++ b/libical/examples/errors.c @@ -32,7 +32,7 @@ void component_errors(icalcomponent *comp) errors = icalcomponent_count_errors(comp); - printf("This component has %d parsing errors\n"); + printf("This component has %d parsing errors\n", errors); /* Print out all of the parsing errors. This is not strictly correct, because it does not descend into any sub-components, diff --git a/libical/examples/main.c b/libical/examples/main.c index 88d6621365..1be2de5c9e 100644 --- a/libical/examples/main.c +++ b/libical/examples/main.c @@ -1,9 +1,12 @@ /* This is just to make the code in the example directory link properly. */ +#include "ical.h" -main() +int main() { + + return 1; } -int do_something(){ +void do_something(icalcomponent* comp){ } diff --git a/libical/examples/parse_text.c b/libical/examples/parse_text.c index 2761e6f951..6de3e76dd5 100644 --- a/libical/examples/parse_text.c +++ b/libical/examples/parse_text.c @@ -25,10 +25,9 @@ char* read_stream(char *s, size_t size, void *d) } -int parse_text(int argc, char* argv[]) +void parse_text(int argc, char* argv[]) { - int lineno = 0; char* line; FILE* stream; icalcomponent *c; diff --git a/libical/src/libical/icalmime.c b/libical/src/libical/icalmime.c index a3fb7deaef..1aaf9c9aa9 100644 --- a/libical/src/libical/icalmime.c +++ b/libical/src/libical/icalmime.c @@ -27,8 +27,11 @@ ======================================================================*/ #include "icalmime.h" +#include "icalerror.h" +#include "icalmemory.h" #include "sspm.h" #include "stdlib.h" +#include /* For strdup */ #ifdef DMALLOC #include "dmalloc.h" @@ -99,6 +102,7 @@ void* icalmime_text_end_part(void* part) void icalmime_text_free_part(void *part) { + part = part; } @@ -111,6 +115,10 @@ void* icalmime_attachment_new_part() void icalmime_attachment_add_line(void *part, struct sspm_header *header, char* line, size_t size) { + part = part; + header = header; + line = line; + size = size; } void* icalmime_attachment_end_part(void* part) @@ -129,6 +137,7 @@ struct sspm_action_map icalmime_local_action_map[] = { {SSPM_TEXT_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_textcalendar_end_part,icalmime_text_free_part}, {SSPM_TEXT_MAJOR_TYPE,SSPM_ANY_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part}, + {SSPM_TEXT_MAJOR_TYPE,SSPM_PLAIN_MINOR_TYPE,icalmime_text_new_part,icalmime_text_add_line,icalmime_text_end_part,icalmime_text_free_part}, {SSPM_APPLICATION_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_IMAGE_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, {SSPM_AUDIO_MAJOR_TYPE,SSPM_CALENDAR_MINOR_TYPE,icalmime_attachment_new_part,icalmime_attachment_add_line,icalmime_attachment_end_part,icalmime_attachment_free_part}, @@ -136,14 +145,22 @@ struct sspm_action_map icalmime_local_action_map[] = {SSPM_UNKNOWN_MAJOR_TYPE,SSPM_UNKNOWN_MINOR_TYPE,0,0,0,0} }; +#define NUM_PARTS 100 /* HACK. Hard Limit */ + + + +struct sspm_part* icalmime_make_part(icalcomponent* comp) +{ + comp = comp; + return 0; +} + +char* icalmime_as_mime_string(char* icalcomponent); icalcomponent* icalmime_parse(char* (*get_string)(char *s, size_t size, void *d), void *data) { - -#define NUM_PARTS 100 /* HACK. Hard Limit */ - struct sspm_part *parts; int i, last_level=0; icalcomponent *root=0, *parent=0, *comp=0, *last = 0; @@ -179,8 +196,6 @@ icalcomponent* icalmime_parse(char* (*get_string)(char *s, size_t size, sprintf(mimetype,"%s/%s",major,minor); - printf("%d: %-10s %p\n",parts[i].level,mimetype,data); - comp = icalcomponent_new(ICAL_XLICMIMEPART_COMPONENT); if(comp == 0){ @@ -205,8 +220,8 @@ icalcomponent* icalmime_parse(char* (*get_string)(char *s, size_t size, } if(parts[i].header.error==SSPM_NO_HEADER_ERROR){ - str = "Did not get a header for the part. Is there a blank -line between the header and the previous boundary?"; + str = "Did not get a header for the part. Is there a blank\ +line between the header and the previous boundary\?"; } @@ -226,15 +241,21 @@ line between the header and the previous boundary?"; 0)); } -#if 0 - icalcomponent_add_property(comp, - icalproperty_new_xlicmimecontenttype((char*)icalmemory_strdup(mimetype))); + if(parts[i].header.major != SSPM_NO_MAJOR_TYPE && + parts[i].header.major != SSPM_UNKNOWN_MAJOR_TYPE){ + + icalcomponent_add_property(comp, + icalproperty_new_xlicmimecontenttype((char*) + icalmemory_strdup(mimetype))); + + } + + if (parts[i].header.encoding != SSPM_NO_ENCODING){ - if (parts[i].header.encoding != 0){ icalcomponent_add_property(comp, - icalproperty_new_xlicmimeencoding(parts[i].header.encoding)); + icalproperty_new_xlicmimeencoding( + sspm_encoding_string(parts[i].header.encoding))); } -#endif if (parts[i].header.filename != 0){ icalcomponent_add_property(comp, @@ -323,3 +344,42 @@ line between the header and the previous boundary?"; +int icalmime_test(char* (*get_string)(char *s, size_t size, void *d), + void *data) +{ + char *out; + struct sspm_part *parts; + int i; + + if ( (parts = (struct sspm_part *) + malloc(NUM_PARTS*sizeof(struct sspm_part)))==0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + memset(parts,0,sizeof(parts)); + + sspm_parse_mime(parts, + NUM_PARTS, /* Max parts */ + icalmime_local_action_map, /* Actions */ + get_string, + data, /* data for get_string*/ + 0 /* First header */); + + for(i = 0; i /* for malloc */ #include /* for errno */ -#include /* for icalmemory_strdup */ +#include /* for strdup */ #include -#include /* for SHRT_MAX */ #define TEMP_MAX 1024 + + enum byrule { NO_CONTRACTION = -1, BY_SECOND = 0, @@ -147,7 +154,7 @@ enum byrule { struct icalrecur_iterator_impl { - struct icaltimetype dtstart; + struct icaltimetype dtstart; /* Hack. Make into time_t */ struct icaltimetype last; /* last time return from _iterator_next*/ int occurrence_no; /* number of step made on this iterator */ struct icalrecurrencetype rule; @@ -181,6 +188,10 @@ enum expand_table { ILLEGAL=3 }; +/* The split map indicates, for a particular interval, wether a BY_* + rule part expands the number of instances in the occcurrence set or + contracts it. 1=> contract, 2=>expand, and 3 means the pairing is + not allowed. */ struct expand_split_map_struct { icalrecurrencetype_frequency frequency; @@ -193,14 +204,14 @@ struct expand_split_map_struct struct expand_split_map_struct expand_map[] = { - {ICAL_SECONDLY_RECURRENCE,1,1,1,1,1,1,1,1}, - {ICAL_MINUTELY_RECURRENCE,2,1,1,1,1,1,1,1}, - {ICAL_HOURLY_RECURRENCE, 2,2,1,1,1,1,1,1}, - {ICAL_DAILY_RECURRENCE, 2,2,2,1,1,1,1,1}, - {ICAL_WEEKLY_RECURRENCE, 2,2,2,2,3,3,1,1}, - {ICAL_MONTHLY_RECURRENCE, 2,2,2,2,2,3,3,1}, - {ICAL_YEARLY_RECURRENCE, 2,2,2,2,2,2,2,2}, - {ICAL_NO_RECURRENCE, 0,0,0,0,0,0,0,0} + {ICAL_SECONDLY_RECURRENCE,{1,1,1,1,1,1,1,1}}, + {ICAL_MINUTELY_RECURRENCE,{2,1,1,1,1,1,1,1}}, + {ICAL_HOURLY_RECURRENCE, {2,2,1,1,1,1,1,1}}, + {ICAL_DAILY_RECURRENCE, {2,2,2,1,1,1,1,1}}, + {ICAL_WEEKLY_RECURRENCE, {2,2,2,2,3,3,1,1}}, + {ICAL_MONTHLY_RECURRENCE, {2,2,2,2,2,3,3,1}}, + {ICAL_YEARLY_RECURRENCE, {2,2,2,2,2,2,2,2}}, + {ICAL_NO_RECURRENCE, {0,0,0,0,0,0,0,0}} }; @@ -278,7 +289,7 @@ void setup_defaults(struct icalrecur_iterator_impl* impl, freq = impl->rule.freq; /* Re-write the BY rule arrays with data from the DTSTART time so - we don't hav to explicitly deal with DTSTART */ + we don't have to explicitly deal with DTSTART */ if(impl->by_ptrs[byrule][0] == ICAL_RECURRENCE_ARRAY_MAX && expand_map[freq].map[byrule] != CONTRACT){ @@ -296,7 +307,8 @@ void setup_defaults(struct icalrecur_iterator_impl* impl, int expand_year_days(struct icalrecur_iterator_impl* impl,short year); -icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart) +icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, + struct icaltimetype dtstart) { struct icalrecur_iterator_impl* impl; icalrecurrencetype_frequency freq; @@ -388,7 +400,9 @@ icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struc /* Rewrite some of the rules and set up defaults to make later - processing easier */ + processing easier. Primarily, this involves copying an element + from the start time into the coresponding BY_* array when the + BY_* array is empty */ setup_defaults(impl,BY_SECOND,ICAL_SECONDLY_RECURRENCE,impl->dtstart.second, @@ -445,63 +459,121 @@ void increment_year(struct icalrecur_iterator_impl* impl, int inc) void increment_month(struct icalrecur_iterator_impl* impl, int inc) { + int years; + impl->last.month+=inc; - if (impl->last.month > 12){ - impl->last.month = 1; - increment_year(impl,1); + /* Months are offset by one */ + impl->last.month--; + + years = impl->last.month / 12; + + impl->last.month = impl->last.month % 12; + + impl->last.month++; + + if (years != 0){ + increment_year(impl,years); } } void increment_monthday(struct icalrecur_iterator_impl* impl, int inc) { - - short days_in_month = icaltime_days_in_month(impl->last.month,impl->last.year); + int i; - impl->last.day+=inc; + for(i=0; ilast.month,impl->last.year); - if (impl->last.day > days_in_month){ - int md = impl->last.day -days_in_month; - impl->last.day = md; - increment_month(impl,1); + impl->last.day++; + + if (impl->last.day > days_in_month){ + impl->last.day = impl->last.day-days_in_month; + increment_month(impl,1); + } } - } void increment_hour(struct icalrecur_iterator_impl* impl, int inc) { + short days; + impl->last.hour+=inc; - if (impl->last.hour > 24){ - impl->last.hour = 0; - increment_monthday(impl,1); - } + days = impl->last.hour / 24; + impl->last.hour = impl->last.hour % 24; + if (impl->days != 0){ + increment_monthday(impl,days); + } } void increment_minute(struct icalrecur_iterator_impl* impl, int inc) { + short hours; + impl->last.minute+=inc; - if (impl->last.minute > 59){ - impl->last.minute = 0; - increment_hour(impl,1); + hours = impl->last.minute / 60; + impl->last.minute = impl->last.minute % 60; + + if (hours != 0){ + increment_hour(impl,hours); } } void increment_second(struct icalrecur_iterator_impl* impl, int inc) { + short minutes; + impl->last.second+=inc; + + minutes = impl->last.second / 60; + impl->last.second = impl->last.second % 60; + + if (minutes != 0) + { + increment_minute(impl, minutes); + } +} - if (impl->last.second > 59){ - impl->last.second = 0; - increment_minute(impl,1); - } +#if 1 + +#include "ical.h" +void test_increment() +{ + struct icalrecur_iterator_impl impl; + + impl.last = icaltime_from_string("20000101T000000Z"); + printf("Orig: %s\n",icaltime_as_ctime(impl.last)); + + increment_second(&impl,5); + printf("+ 5 sec : %s\n",icaltime_as_ctime(impl.last)); + + increment_second(&impl,355); + printf("+ 355 sec : %s\n",icaltime_as_ctime(impl.last)); + + increment_minute(&impl,5); + printf("+ 5 min : %s\n",icaltime_as_ctime(impl.last)); + + increment_minute(&impl,360); + printf("+ 360 min : %s\n",icaltime_as_ctime(impl.last)); + increment_hour(&impl,5); + printf("+ 5 hours : %s\n",icaltime_as_ctime(impl.last)); + increment_hour(&impl,43); + printf("+ 43 hours : %s\n",icaltime_as_ctime(impl.last)); + increment_monthday(&impl,3); + printf("+ 3 days : %s\n",icaltime_as_ctime(impl.last)); + increment_monthday(&impl,600); + printf("+ 600 days : %s\n",icaltime_as_ctime(impl.last)); + } +#endif short next_second(struct icalrecur_iterator_impl* impl) { @@ -766,6 +838,8 @@ int next_weekday(struct icalrecur_iterator_impl* impl) end_of_data = 1; } + /* HACK. I don't think this handles the Nth day of week rules + correctly ( "BYDAY=2TU" ) */ dow = impl->by_ptrs[BY_DAY][impl->by_indices[BY_DAY]]; start_of_week = icaltime_start_doy_of_week(impl->last); @@ -1146,29 +1220,94 @@ struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *itr) return impl->last; } -#include "ical.h" -void icalrecurrencetype_test() + +/************************** Type Routines **********************/ + + +void icalrecurrencetype_clear(struct icalrecurrencetype *recur) { - icalvalue *v = icalvalue_new_from_string( - ICAL_RECUR_VALUE, - "FREQ=YEARLY;UNTIL=20060101T000000;INTERVAL=2;BYDAY=SU,WE;BYSECOND=15,30; BYMONTH=1,6,11"); + memset(recur,ICAL_RECURRENCE_ARRAY_MAX_BYTE, + sizeof(struct icalrecurrencetype)); + + recur->week_start = ICAL_MONDAY_WEEKDAY; + recur->freq = ICAL_NO_RECURRENCE; + recur->interval = 1; + memset(&(recur->until),0,sizeof(struct icaltimetype)); + recur->count = 0; +} - struct icalrecurrencetype r = icalvalue_get_recur(v); - struct icaltimetype t = icaltime_from_timet( time(0), 0, 0); - struct icaltimetype next; - time_t tt; +/* The 'day' element of icalrecurrencetype_weekday is encoded to allow +reporesentation of both the day of the week ( Monday, Tueday), but +also the Nth day of the week ( First tuesday of the month, last +thursday of the year) These routines decode the day values. - struct icalrecur_iterator_impl* itr - = (struct icalrecur_iterator_impl*) icalrecur_iterator_new(r,t); +The day's position in the period ( Nth-ness) and the numerical value +of the day are encoded together as: pos*7 + dow + */ - do { +enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day) +{ + return abs(day)%8; +} + +short icalrecurrencetype_day_position(short day) +{ + return (day-icalrecurrencetype_day_day_of_week(day))/8; +} - next = icalrecur_iterator_next(itr); - tt = icaltime_as_timet(next); - printf("%s",ctime(&tt )); +/****************** Enumeration Routines ******************/ + +struct {icalrecurrencetype_weekday wd; const char * str; } +wd_map[] = { + {ICAL_SUNDAY_WEEKDAY,"SU"}, + {ICAL_MONDAY_WEEKDAY,"MO"}, + {ICAL_TUESDAY_WEEKDAY,"TU"}, + {ICAL_WEDNESDAY_WEEKDAY,"WE"}, + {ICAL_THURSDAY_WEEKDAY,"TH"}, + {ICAL_FRIDAY_WEEKDAY,"FR"}, + {ICAL_SATURDAY_WEEKDAY,"SA"}, + {ICAL_NO_WEEKDAY,0} +}; + +const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind) +{ + int i; - } while( ! icaltime_is_null_time(next)); - + for (i=0; wd_map[i].wd != ICAL_NO_WEEKDAY; i++) { + if ( wd_map[i].wd == kind) { + return wd_map[i].str; + } + } + + return 0; } + +struct { + icalrecurrencetype_frequency kind; + const char* str; +} freq_map[] = { + {ICAL_SECONDLY_RECURRENCE,"SECONDLY"}, + {ICAL_MINUTELY_RECURRENCE,"MINUTELY"}, + {ICAL_HOURLY_RECURRENCE,"HOURLY"}, + {ICAL_DAILY_RECURRENCE,"DAILY"}, + {ICAL_WEEKLY_RECURRENCE,"WEEKLY"}, + {ICAL_MONTHLY_RECURRENCE,"MONTHLY"}, + {ICAL_YEARLY_RECURRENCE,"YEARLY"}, + {ICAL_NO_RECURRENCE,0} +}; + +const char* icalrecur_recurrence_to_string(icalrecurrencetype_frequency kind) +{ + int i; + + for (i=0; freq_map[i].kind != ICAL_NO_RECURRENCE ; i++) { + if ( freq_map[i].kind == kind ) { + return freq_map[i].str; + } + } + return 0; +} + + diff --git a/libical/src/libical/icalrecur.h b/libical/src/libical/icalrecur.h index cfafc01b02..fe82ff960c 100644 --- a/libical/src/libical/icalrecur.h +++ b/libical/src/libical/icalrecur.h @@ -17,7 +17,6 @@ The Mozilla Public License Version 1.0. You may obtain a copy of the License at http://www.mozilla.org/MPL/ - The original code is icaltypes.h ======================================================================*/ @@ -25,13 +24,116 @@ #define ICALRECUR_H #include -#include "icaltypes.h" -#include "icalenums.h" /* for recurrence enums */ +#include "icaltime.h" + + +/*********************************************************************** + * Recurrance enumerations +**********************************************************************/ + +typedef enum icalrecurrencetype_frequency +{ + /* These enums are used to index an array, so don't change the + order or the integers */ + + ICAL_SECONDLY_RECURRENCE=0, + ICAL_MINUTELY_RECURRENCE=1, + ICAL_HOURLY_RECURRENCE=2, + ICAL_DAILY_RECURRENCE=3, + ICAL_WEEKLY_RECURRENCE=4, + ICAL_MONTHLY_RECURRENCE=5, + ICAL_YEARLY_RECURRENCE=6, + ICAL_NO_RECURRENCE=7 + +} icalrecurrencetype_frequency; + +typedef enum icalrecurrencetype_weekday +{ + ICAL_NO_WEEKDAY, + ICAL_SUNDAY_WEEKDAY, + ICAL_MONDAY_WEEKDAY, + ICAL_TUESDAY_WEEKDAY, + ICAL_WEDNESDAY_WEEKDAY, + ICAL_THURSDAY_WEEKDAY, + ICAL_FRIDAY_WEEKDAY, + ICAL_SATURDAY_WEEKDAY +} icalrecurrencetype_weekday; + +enum { + ICAL_RECURRENCE_ARRAY_MAX = 0x7f7f, + ICAL_RECURRENCE_ARRAY_MAX_BYTE = 0x7f +}; + +const char* icalrecur_recurrence_to_string(icalrecurrencetype_frequency kind); +const char* icalrecur_weekday_to_string(icalrecurrencetype_weekday kind); + + +/********************** Recurrence type routines **************/ + +/* See RFC 2445 Section 4.3.10, RECUR Value, for an explaination of + the values and fields in struct icalrecurrencetype */ + + +struct icalrecurrencetype +{ + icalrecurrencetype_frequency freq; + + + /* until and count are mutually exclusive. */ + struct icaltimetype until; /* Hack. Must be time_t for general use */ + int count; + + short interval; + + icalrecurrencetype_weekday week_start; + + /* The BY* parameters can each take a list of values. Here I + * assume that the list of values will not be larger than the + * range of the value -- that is, the client will not name a + * value more than once. + + * Each of the lists is terminated with the value + * ICALRECURRENCE_ARRAY_MAX unless the the list is full. + */ + + short by_second[61]; + short by_minute[61]; + short by_hour[25]; + short by_day[8]; /* Encoded value, see below */ + short by_month_day[32]; + short by_year_day[367]; + short by_week_no[54]; + short by_month[13]; + short by_set_pos[367]; +}; + + +void icalrecurrencetype_clear(struct icalrecurrencetype *r); + +/* The 'day' element of icalrecurrencetype_weekday is encoded to allow +representation of both the day of the week ( Monday, Tueday), but also +the Nth day of the week ( First tuesday of the month, last thursday of +the year) These routines decode the day values */ + +/* 1 == Monday, etc. */ +enum icalrecurrencetype_weekday icalrecurrencetype_day_day_of_week(short day); + +/* 0 == any of day of week. 1 == first, 2 = second, -2 == second to last, etc */ +short icalrecurrencetype_day_position(short day); + +/* Return the next occurance of 'r' after the time specified by 'after' */ +struct icaltimetype icalrecurrencetype_next_occurance( + struct icalrecurrencetype *r, + struct icaltimetype *after); + + typedef void icalrecur_iterator; void icalrecurrencetype_test(); +/********** recurrence routines ********************/ + icalrecur_iterator* icalrecur_iterator_new(struct icalrecurrencetype rule, struct icaltimetype dtstart); struct icaltimetype icalrecur_iterator_next(icalrecur_iterator*); diff --git a/libical/src/libical/sspm.c b/libical/src/libical/sspm.c index 36f69b506a..faaacb5592 100644 --- a/libical/src/libical/sspm.c +++ b/libical/src/libical/sspm.c @@ -125,6 +125,21 @@ struct minor_content_type_map +struct encoding_map { + enum sspm_encoding encoding; + char* str; +} sspm_encoding_map[] = +{ + {SSPM_NO_ENCODING,""}, + {SSPM_QUOTED_PRINTABLE_ENCODING,"quoted-printable"}, + {SSPM_8BIT_ENCODING,"8bit"}, + {SSPM_7BIT_ENCODING,"7bit"}, + {SSPM_BINARY_ENCODING,"binary"}, + {SSPM_BASE64_ENCODING,"base64"}, + {SSPM_UNKNOWN_ENCODING,""} + +}; + char* sspm_get_parameter(char* line, char* parameter) { @@ -488,6 +503,19 @@ char* sspm_minor_type_string(enum sspm_major_type type) } +char* sspm_encoding_string(enum sspm_encoding type) +{ + int i; + for (i=0; sspm_encoding_map[i].encoding != SSPM_UNKNOWN_ENCODING; + i++){ + if(type == sspm_encoding_map[i].encoding){ + return sspm_encoding_map[i].str; + } + } + + return sspm_encoding_map[i].str; /* Should return SSPM_UNKNOWN_MINOR_TYPE */ +} + /* Interpret a header line and add its data to the header structure. */ void sspm_build_header(struct sspm_header *header, char* line) @@ -543,6 +571,7 @@ void sspm_build_header(struct sspm_header *header, char* line) header->encoding = SSPM_UNKNOWN_ENCODING; } + free(lencoding); header->def = 0; @@ -570,12 +599,13 @@ char* sspm_get_next_line(struct mime_impl *impl) void sspm_store_part(struct mime_impl *impl, struct sspm_header header, - int level, void *part) + int level, void *part, size_t size) { impl->parts[impl->part_no].header = header; impl->parts[impl->part_no].level = level; impl->parts[impl->part_no].data = part; + impl->parts[impl->part_no].data_size = size; impl->part_no++; } @@ -599,8 +629,10 @@ void sspm_set_error(struct sspm_header* header, enum sspm_error error, } void* sspm_make_part(struct mime_impl *impl, - struct sspm_header *header, - struct sspm_header *parent_header) + struct sspm_header *header, + struct sspm_header *parent_header, + void **end_part, + size_t *size) { /* For a single part type, read to the boundary, if there is a @@ -609,7 +641,7 @@ void* sspm_make_part(struct mime_impl *impl, at the first blank line */ char *line; - void *part, *end_part; + void *part; int end = 0; struct sspm_action_map action = get_action( @@ -617,6 +649,7 @@ void* sspm_make_part(struct mime_impl *impl, header->major, header->minor); + *size = 0; part =action.new_part(); impl->state = IN_BODY; @@ -630,7 +663,7 @@ void* sspm_make_part(struct mime_impl *impl, if(parent_header == 0){ char* boundary; end = 1; - end_part = 0; + *end_part = 0; sspm_set_error(header,SSPM_UNEXPECTED_BOUNDARY_ERROR,line); @@ -654,7 +687,7 @@ void* sspm_make_part(struct mime_impl *impl, if(strncmp((line+2),parent_header->boundary, sizeof(parent_header->boundary)) == 0){ - end_part = action.end_part(part); + *end_part = action.end_part(part); if(sspm_is_mime_boundary(line)){ impl->state = END_OF_PART; @@ -684,7 +717,6 @@ void* sspm_make_part(struct mime_impl *impl, strcpy(boundary,line); strcat(boundary,"--"); while((line = sspm_get_next_line(impl)) != 0){ - /*printf("Error: %s\n",line);*/ if(strcmp(boundary,line)==0){ break; } @@ -693,16 +725,16 @@ void* sspm_make_part(struct mime_impl *impl, } } else { - size_t size; - char* data; + char* data=0; char* rtrn=0; - size = strlen(line); + *size = strlen(line); - data = (char*)malloc(size+2); + data = (char*)malloc(*size+2); + assert(data != 0); if (header->encoding == SSPM_BASE64_ENCODING){ - rtrn = decode_base64(data,line,&size); + rtrn = decode_base64(data,line,size); } else if(header->encoding == SSPM_QUOTED_PRINTABLE_ENCODING){ - rtrn = decode_quoted_printable(data,line,&size); + rtrn = decode_quoted_printable(data,line,size); } if(rtrn == 0){ @@ -712,9 +744,9 @@ void* sspm_make_part(struct mime_impl *impl, /* add a end-of-string after the data, just in case binary data from decode64 gets passed to a tring handling routine in add_line */ - data[size+1]='\0'; + data[*size+1]='\0'; - action.add_line(part,header,data,size); + action.add_line(part,header,data,*size); free(data); } @@ -722,7 +754,7 @@ void* sspm_make_part(struct mime_impl *impl, if (end == 0){ /* End the part if the input is exhausted */ - end_part = action.end_part(part); + *end_part = action.end_part(part); } return end_part; @@ -735,6 +767,7 @@ void* sspm_make_multipart_subpart(struct mime_impl *impl, struct sspm_header header; char *line; void* part; + size_t size; if(parent_header->boundary == 0){ /* Error. Multipart headers must have a boundary*/ @@ -785,7 +818,6 @@ void* sspm_make_multipart_subpart(struct mime_impl *impl, strcpy(boundary,line); strcat(boundary,"--"); while((line = sspm_get_next_line(impl)) != 0){ - /*printf("Error: %s\n",line);*/ if(strcmp(boundary,line)==0){ break; } @@ -809,7 +841,7 @@ void* sspm_make_multipart_subpart(struct mime_impl *impl, } if(header.error!= SSPM_NO_ERROR){ - sspm_store_part(impl,header,impl->level,0); + sspm_store_part(impl,header,impl->level,0,0); return 0; } @@ -820,7 +852,7 @@ void* sspm_make_multipart_subpart(struct mime_impl *impl, child_header = &(impl->parts[impl->part_no].header); /* Store the multipart part */ - sspm_store_part(impl,header,impl->level,0); + sspm_store_part(impl,header,impl->level,0,0); /* now get all of the sub-parts */ part = sspm_make_multipart_part(impl,child_header); @@ -834,11 +866,11 @@ void* sspm_make_multipart_subpart(struct mime_impl *impl, sspm_get_next_line(impl); /* Step past the terminating boundary */ } else { - part = sspm_make_part(impl, &header,parent_header); + sspm_make_part(impl, &header,parent_header,&part,&size); memset(&(impl->parts[impl->part_no]), 0, sizeof(struct sspm_part)); - sspm_store_part(impl,header,impl->level,part); + sspm_store_part(impl,header,impl->level,part,size); } @@ -1013,16 +1045,18 @@ int sspm_parse_mime(struct sspm_part *parts, struct sspm_header *child_header; child_header = &(impl.parts[impl.part_no].header); - sspm_store_part(&impl,header,impl.level,0); + sspm_store_part(&impl,header,impl.level,0,0); part = sspm_make_multipart_part(&impl,child_header); } else { - part = sspm_make_part(&impl, &header, 0); + void *part; + size_t size; + sspm_make_part(&impl, &header, 0,&part,&size); memset(&(impl.parts[impl.part_no]), 0, sizeof(struct sspm_part)); - sspm_store_part(&impl,header,impl.level,part); + sspm_store_part(&impl,header,impl.level,part,size); } return 0; @@ -1076,8 +1110,8 @@ The code is heavily modified by Eric Busboom. ***********************************************************************/ -unsigned char *decode_quoted_printable(unsigned char *dest, - unsigned char *src, +char *decode_quoted_printable(char *dest, + char *src, size_t *size) { int cc; @@ -1125,12 +1159,12 @@ unsigned char *decode_quoted_printable(unsigned char *dest, return(dest); } -unsigned char *decode_base64(unsigned char *dest, - unsigned char *src, - size_t *size) +char *decode_base64(char *dest, + char *src, + size_t *size) { int cc; - unsigned char buf[4] = {0,0,0,0}; + char buf[4] = {0,0,0,0}; int p = 0; int valid_data = 0; size_t size_out=0; @@ -1189,3 +1223,391 @@ unsigned char *decode_base64(unsigned char *dest, } +/*********************************************************************** + + Routines to output MIME + +**********************************************************************/ + + +struct sspm_buffer { + char* buffer; + char* pos; + size_t buf_size; + int line_pos; +}; + +void sspm_append_string(struct sspm_buffer* buf, char* string); +void sspm_write_part(struct sspm_buffer *buf,struct sspm_part *part, int *part_num); + +void sspm_append_hex(struct sspm_buffer* buf, char ch) +{ + char tmp[3]; + + sprintf(tmp,"=%02X",ch); + + sspm_append_string(buf,tmp); +} + +/* a copy of icalmemory_append_char */ +void sspm_append_char(struct sspm_buffer* buf, char ch) +{ + char *new_buf; + char *new_pos; + + size_t data_length, final_length; + + data_length = (size_t)buf->pos - (size_t)buf->buffer; + + final_length = data_length + 2; + + if ( final_length > (size_t) buf->buf_size ) { + + buf->buf_size = (buf->buf_size) * 2 + final_length +1; + + new_buf = realloc(buf->buffer,buf->buf_size); + + new_pos = (void*)((size_t)new_buf + data_length); + + buf->pos = new_pos; + buf->buffer = new_buf; + } + + *(buf->pos) = ch; + buf->pos += 1; + *(buf->pos) = 0; +} +/* A copy of icalmemory_append_string */ +void sspm_append_string(struct sspm_buffer* buf, char* string) +{ + char *new_buf; + char *new_pos; + + size_t data_length, final_length, string_length; + + string_length = strlen(string); + data_length = (size_t)buf->pos - (size_t)buf->buffer; + final_length = data_length + string_length; + + if ( final_length >= (size_t) buf->buf_size) { + + + buf->buf_size = (buf->buf_size) * 2 + final_length; + + new_buf = realloc(buf->buffer,buf->buf_size); + + new_pos = (void*)((size_t)new_buf + data_length); + + buf->pos = new_pos; + buf->buffer = new_buf; + } + + strcpy(buf->pos, string); + + buf->pos += string_length; +} + + + +static int sspm_is_printable(char c) +{ + return (c >= 33) && (c <= 126) && (c != '='); + +} + + +void sspm_encode_quoted_printable(struct sspm_buffer *buf, char* data) +{ + char *p; + int lpos = 0; + + for(p = data; *p != 0; p++){ + + if(sspm_is_printable(*p)){ + /* plain characters can represent themselves */ + /* RFC2045 Rule #2 */ + sspm_append_char(buf,*p); + lpos++; + } else if ( *p == '\t' || *p == ' ' ) { + + /* For tabs and spaces, only encode if they appear at the + end of the line */ + /* RFC2045 Rule #3 */ + + char n = *(p+1); + + if( n == '\n' || n == '\r'){ + sspm_append_hex(buf,*p); + lpos += 3; + } else { + sspm_append_char(buf,*p); + lpos++; + } + + } else if( *p == '\n' || *p == '\r'){ + sspm_append_char(buf,*p); + + lpos=0; + + } else { + /* All others need to be encoded */ + sspm_append_hex(buf,*p); + lpos+=3; + } + + + /* Add line breaks */ + if (lpos > 72){ + lpos = 0; + sspm_append_string(buf,"=\n"); + } + } +} + +static char BaseTable[64] = { + 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3','4','5','6','7','8','9','+','/' +}; + +void sspm_write_base64(struct sspm_buffer *buf, char* inbuf,int size ) +{ + + char outbuf[4]; + int i; + + outbuf[0] = outbuf[1] = outbuf[2] = outbuf[3] = 65; + + switch(size){ + + case 4: + outbuf[3] = inbuf[2] & 0x3F; + + case 3: + outbuf[2] = ((inbuf[1] & 0x0F) << 2) | ((inbuf[2] & 0xC0) >> 6); + + case 2: + outbuf[0] = (inbuf[0] & 0xFC) >> 2; + outbuf[1] = ((inbuf[0] & 0x03) << 4) | ((inbuf[1] & 0xF0) >> 4); + break; + + default: + assert(0); + } + + for(i = 0; i < 4; i++){ + + if(outbuf[i] == 65){ + sspm_append_char(buf,'='); + } else { + sspm_append_char(buf,BaseTable[(int)outbuf[i]]); + } + } +} + +void sspm_encode_base64(struct sspm_buffer *buf, char* data, size_t size) +{ + + char *p; + char inbuf[3]; + int i = 0; + int first = 1; + int lpos = 0; + + inbuf[0] = inbuf[1] = inbuf[2] = 0; + + for (p = data; *p !=0; p++){ + + if (i%3 == 0 && first == 0){ + + sspm_write_base64(buf, inbuf, 4); + lpos+=4; + + inbuf[0] = inbuf[1] = inbuf[2] = 0; + } + + assert(lpos%4 == 0); + + if (lpos == 72){ + sspm_append_string(buf,"\n"); + lpos = 0; + } + + inbuf[i%3] = *p; + + i++; + first = 0; + + } + + + /* If the inbuf was not exactly filled on the last byte, we need + to spit out the odd bytes that did get in -- either one or + two. This will result in an output of two bytes and '==' or + three bytes and '=', respectively */ + + if (i%3 == 1 && first == 0){ + sspm_write_base64(buf, inbuf, 2); + } else if (i%3 == 2 && first == 0){ + sspm_write_base64(buf, inbuf, 3); + } + +} + +void sspm_write_header(struct sspm_buffer *buf,struct sspm_header *header) +{ + + int i; + char temp[TMP_BUF_SIZE]; + char* major; + char* minor; + + /* Content-type */ + + major = sspm_major_type_string(header->major); + minor = sspm_minor_type_string(header->minor); + + if(header->minor == SSPM_UNKNOWN_MINOR_TYPE ){ + assert(header->minor_text !=0); + minor = header->minor_text; + } + + sprintf(temp,"Content-Type: %s/%s",major,minor); + + sspm_append_string(buf,temp); + + if(header->boundary != 0){ + sprintf(temp,";boundary=\"%s\"",header->boundary); + sspm_append_string(buf,temp); + } + + /* Append any content type parameters */ + if(header->content_type_params != 0){ + for(i=0; *(header->content_type_params[i])!= 0;i++){ + sprintf(temp,header->content_type_params[i]); + sspm_append_char(buf,';'); + sspm_append_string(buf,temp); + } + } + + sspm_append_char(buf,'\n'); + + /*Content-Transfer-Encoding */ + + if(header->encoding != SSPM_UNKNOWN_ENCODING && + header->encoding != SSPM_NO_ENCODING){ + sprintf(temp,"Content-Transfer-Encoding: %s\n", + sspm_encoding_string(header->encoding)); + } + + sspm_append_char(buf,'\n'); + +} + +void sspm_write_multipart_part(struct sspm_buffer *buf, + struct sspm_part *parts, + int* part_num) +{ + + int parent_level, level; + struct sspm_header *header = &(parts[*part_num].header); + /* Write the header for the multipart part */ + sspm_write_header(buf,header); + + parent_level = parts[*part_num].level; + + (*part_num)++; + + level = parts[*part_num].level; + + while(parts[*part_num].header.major != SSPM_NO_MAJOR_TYPE && + level == parent_level+1){ + + assert(header->boundary); + sspm_append_string(buf,header->boundary); + sspm_append_char(buf,'\n'); + + if (parts[*part_num].header.major == SSPM_MULTIPART_MAJOR_TYPE){ + sspm_write_multipart_part(buf,parts,part_num); + } else { + sspm_write_part(buf, &(parts[*part_num]), part_num); + } + + (*part_num)++; + level = parts[*part_num].level; + } + + sspm_append_string(buf,"\n\n--"); + sspm_append_string(buf,header->boundary); + sspm_append_string(buf,"\n"); + + (*part_num)--; /* undo last, spurious, increment */ +} + +void sspm_write_part(struct sspm_buffer *buf,struct sspm_part *part,int *part_num) +{ + + /* Write header */ + sspm_write_header(buf,&(part->header)); + + /* Write part data */ + + if(part->data == 0){ + return; + } + + if(part->header.encoding == SSPM_BASE64_ENCODING) { + assert(part->data_size != 0); + sspm_encode_base64(buf,part->data,part->data_size); + } else if(part->header.encoding == SSPM_QUOTED_PRINTABLE_ENCODING) { + sspm_encode_quoted_printable(buf,part->data); + } else { + sspm_append_string(buf,part->data); + } + + sspm_append_string(buf,"\n\n"); +} + +int sspm_write_mime(struct sspm_part *parts,size_t num_parts, + char **output_string, char* header) +{ + struct sspm_buffer buf; + int part_num =0; + + buf.buffer = malloc(4096); + buf.pos = buf.buffer; + buf.buf_size = 10; + buf.line_pos = 0; + + /* write caller's header */ + if(header != 0){ + sspm_append_string(&buf,header); + } + + if(buf.buffer[strlen(buf.buffer)-1] != '\n'){ + sspm_append_char(&buf,'\n'); + } + + /* write mime-version header */ + sspm_append_string(&buf,"Mime-Version: 1.0\n"); + + /* End of header */ + + /* Write body parts */ + while(parts[part_num].header.major != SSPM_NO_MAJOR_TYPE){ + if (parts[part_num].header.major == SSPM_MULTIPART_MAJOR_TYPE){ + sspm_write_multipart_part(&buf,parts,&part_num); + } else { + sspm_write_part(&buf, &(parts[part_num]), &part_num); + } + + part_num++; + } + + + *output_string = buf.buffer; + + return 0; +} + diff --git a/libical/src/libical/sspm.h b/libical/src/libical/sspm.h index 657b77a8d7..417f83eefd 100644 --- a/libical/src/libical/sspm.h +++ b/libical/src/libical/sspm.h @@ -37,6 +37,7 @@ #define SSPM_H enum sspm_major_type { + SSPM_NO_MAJOR_TYPE, SSPM_TEXT_MAJOR_TYPE, SSPM_IMAGE_MAJOR_TYPE, SSPM_AUDIO_MAJOR_TYPE, @@ -44,11 +45,11 @@ enum sspm_major_type { SSPM_APPLICATION_MAJOR_TYPE, SSPM_MULTIPART_MAJOR_TYPE, SSPM_MESSAGE_MAJOR_TYPE, - SSPM_UNKNOWN_MAJOR_TYPE, - SSPM_NO_MAJOR_TYPE + SSPM_UNKNOWN_MAJOR_TYPE }; enum sspm_minor_type { + SSPM_NO_MINOR_TYPE, SSPM_ANY_MINOR_TYPE, SSPM_PLAIN_MINOR_TYPE, SSPM_RFC822_MINOR_TYPE, @@ -58,8 +59,7 @@ enum sspm_minor_type { SSPM_RELATED_MINOR_TYPE, SSPM_ALTERNATIVE_MINOR_TYPE, SSPM_PARALLEL_MINOR_TYPE, - SSPM_UNKNOWN_MINOR_TYPE, - SSPM_NO_MINOR_TYPE + SSPM_UNKNOWN_MINOR_TYPE }; enum sspm_encoding { @@ -89,6 +89,7 @@ struct sspm_header enum sspm_major_type major; enum sspm_minor_type minor; char *minor_text; + char ** content_type_params; char* charset; enum sspm_encoding encoding; char* filename; @@ -100,6 +101,7 @@ struct sspm_header struct sspm_part { struct sspm_header header; int level; + size_t data_size; void *data; }; @@ -115,7 +117,7 @@ struct sspm_action_map { char* sspm_major_type_string(enum sspm_major_type type); char* sspm_minor_type_string(enum sspm_major_type type); - +char* sspm_encoding_string(enum sspm_encoding type); int sspm_parse_mime(struct sspm_part *parts, size_t max_parts, @@ -127,12 +129,15 @@ int sspm_parse_mime(struct sspm_part *parts, void sspm_free_parts(struct sspm_part *parts, size_t max_parts); -unsigned char *decode_quoted_printable(unsigned char *dest, - unsigned char *src, - size_t *size); -unsigned char *decode_base64(unsigned char *dest, - unsigned char *src, +char *decode_quoted_printable(char *dest, + char *src, size_t *size); +char *decode_base64(char *dest, + char *src, + size_t *size); + +int sspm_write_mime(struct sspm_part *parts,size_t num_parts, + char **output_string, char* header); -#endif SSPM_H +#endif /*SSPM_H*/ diff --git a/libical/src/libicalss/icaldirset.c b/libical/src/libicalss/icaldirset.c index ff5357126c..b377d54571 100644 --- a/libical/src/libicalss/icaldirset.c +++ b/libical/src/libicalss/icaldirset.c @@ -31,11 +31,10 @@ icaldirset manages a database of ical components and offers interfaces for reading, writting and searching for components. - icaldirset groups components in to clusters based on their DTSTART + icaldirset groups components in to clusters based on their DTSTAMP time -- all components that start in the same month are grouped together in a single file. All files in a sotre are kept in a single - directory. ( If a component does not have DTSTART, the store uses - DTSTAMP or CREATE ) + directory. The primary interfaces are icaldirset_first and icaldirset_next. These routine iterate through all of the components in the store, subject @@ -76,32 +75,25 @@ #include /* for rand(), srand() */ #include /* for uname */ #include /* for strdup */ +#include "icaldirsetimpl.h" -struct icaldirset_impl -{ - char* dir; - icalcomponent* gauge; - icaldirset* cluster; - int first_component; - pvl_list directory; - pvl_elem directory_iterator; -}; - struct icaldirset_impl* icaldirset_new_impl() { - struct icaldirset_impl* comp; + struct icaldirset_impl* impl; - if ( ( comp = (struct icaldirset_impl*) + if ( ( impl = (struct icaldirset_impl*) malloc(sizeof(struct icaldirset_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); return 0; } - return comp; + strcpy(impl->id,ICALDIRSET_ID); + + return impl; } -char* icaldirset_path(icaldirset* cluster) +const char* icaldirset_path(icaldirset* cluster) { struct icaldirset_impl *impl = icaldirset_new_impl(); @@ -125,12 +117,12 @@ icalerrorenum icaldirset_commit(icaldirset* store) } -void icaldirset_lock(char* dir) +void icaldirset_lock(const char* dir) { } -void icaldirset_unlock(char* dir) +void icaldirset_unlock(const char* dir) { } @@ -172,7 +164,7 @@ icalerrorenum icaldirset_read_directory(struct icaldirset_impl* impl) return ICAL_NO_ERROR; } -icaldirset* icaldirset_new(char* dir) +icaldirset* icaldirset_new(const char* dir) { struct icaldirset_impl *impl = icaldirset_new_impl(); struct stat sbuf; @@ -366,7 +358,7 @@ void icaldirset_add_uid(icaldirset* store, icaldirset* comp) /* This assumes that the top level component is a VCALENDAR, and there is an inner component of type VEVENT, VTODO or VJOURNAL. The inner - component must have a DTSTART property */ + component must have a DTAMP property */ icalerrorenum icaldirset_add_component(icaldirset* store, icaldirset* comp) { @@ -392,15 +384,32 @@ icalerrorenum icaldirset_add_component(icaldirset* store, icaldirset* comp) inner != 0; inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ - dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); - + dt = icalcomponent_get_first_property(inner,ICAL_DTSTAMP_PROPERTY); + if (dt != 0){ break; } } if (dt == 0){ - icalerror_warn("The component does not have a DTSTART property, so it cannot be added to the store"); + + for(inner = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT); + inner != 0; + inner = icalcomponent_get_next_component(comp,ICAL_ANY_COMPONENT)){ + + dt = icalcomponent_get_first_property(inner,ICAL_DTSTART_PROPERTY); + + if (dt != 0){ + break; + } + } + + } + + if (dt == 0){ + + + icalerror_warn("The component does not have a DTSTAMP or DTSTART property, so it cannot be added to the store"); icalerror_set_errno(ICAL_BADARG_ERROR); return ICAL_BADARG_ERROR; } @@ -488,7 +497,7 @@ icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp) icalerrorenum error = icaldirset_next_cluster(store); if(impl->cluster != 0 && error == ICAL_NO_ERROR){ - icalfileset_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); + icalfileset_get_first_component(impl->cluster); } else { /* HACK. Not strictly correct for impl->cluster==0 */ return error; @@ -503,10 +512,24 @@ icalerrorenum icaldirset_remove_component(icaldirset* store, icaldirset* comp) int icaldirset_count_components(icaldirset* store, - icalcomponent_kind kind); + icalcomponent_kind kind) +{ + /* HACK, not implemented */ + + assert(0); + + return 0; +} + + +icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c) +{ + fprintf(stderr," icaldirset_fetch_match is not implemented\n"); + assert(0); +} -icalcomponent* icaldirset_fetch(icaldirset* store, char* uid) +icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid) { icalcomponent *gauge; icalcomponent *old_gauge; @@ -532,7 +555,7 @@ icalcomponent* icaldirset_fetch(icaldirset* store, char* uid) old_gauge = impl->gauge; impl->gauge = gauge; - c= icaldirset_get_first_component(store,ICAL_ANY_COMPONENT); + c= icaldirset_get_first_component(store); impl->gauge = old_gauge; @@ -542,7 +565,7 @@ icalcomponent* icaldirset_fetch(icaldirset* store, char* uid) } -int icaldirset_has_uid(icaldirset* store, char* uid) +int icaldirset_has_uid(icaldirset* store, const char* uid) { icalcomponent *c; @@ -560,7 +583,7 @@ int icaldirset_has_uid(icaldirset* store, char* uid) icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge) -{ + { struct icaldirset_impl *impl = (struct icaldirset_impl*)store; icalerror_check_arg_re( (store!=0), "store",ICAL_BADARG_ERROR); @@ -575,16 +598,30 @@ icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge) return ICAL_NO_ERROR; } -void icaldirset_clear(icaldirset* store); -icalcomponent* icaldirset_fetch(icaldirset* store, char* uid); -int icaldirset_has_uid(icaldirset* store, char* uid); + +icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *old, + icalcomponent *new) +{ + assert(0); + return ICAL_NO_ERROR; /* HACK, not implemented */ + +} + + +void icaldirset_clear(icaldirset* store) +{ + + assert(0); + return; + /* HACK, not implemented */ +} icalcomponent* icaldirset_get_current_component(icaldirset* store) { struct icaldirset_impl *impl = (struct icaldirset_impl*)store; if(impl->cluster == 0){ - icaldirset_get_first_component(store,ICAL_ANY_COMPONENT); + icaldirset_get_first_component(store); } return icalfileset_get_current_component(impl->cluster); @@ -592,8 +629,7 @@ icalcomponent* icaldirset_get_current_component(icaldirset* store) } -icalcomponent* icaldirset_get_first_component(icaldirset* store, - icalcomponent_kind kind) +icalcomponent* icaldirset_get_first_component(icaldirset* store) { struct icaldirset_impl *impl = (struct icaldirset_impl*)store; icalerrorenum error; @@ -638,11 +674,10 @@ icalcomponent* icaldirset_get_first_component(icaldirset* store, impl->first_component = 1; - return icaldirset_get_next_component(store, kind); + return icaldirset_get_next_component(store); } -icalcomponent* icaldirset_get_next_component(icaldirset* store, - icalcomponent_kind kind) +icalcomponent* icaldirset_get_next_component(icaldirset* store) { struct icaldirset_impl *impl; icalcomponent *c; @@ -662,10 +697,10 @@ icalcomponent* icaldirset_get_next_component(icaldirset* store, /* Set the component iterator for the following for loop */ if (impl->first_component == 1){ - icalfileset_get_first_component(impl->cluster,kind); + icalfileset_get_first_component(impl->cluster); impl->first_component = 0; } else { - icalfileset_get_next_component(impl->cluster,kind); + icalfileset_get_next_component(impl->cluster); } @@ -673,9 +708,7 @@ icalcomponent* icaldirset_get_next_component(icaldirset* store, /* Iterate through all of the objects in the cluster*/ for( c = icalfileset_get_current_component(impl->cluster); c != 0; - c = icalfileset_get_next_component( - impl->cluster, - kind)){ + c = icalfileset_get_next_component(impl->cluster)){ /* If there is a gauge defined and the component does not pass the gauge, skip the rest of the loop */ @@ -698,9 +731,7 @@ icalcomponent* icaldirset_get_next_component(icaldirset* store, /* No more clusters */ return 0; } else { - c = icalfileset_get_first_component( - impl->cluster, - kind); + c = icalfileset_get_first_component(impl->cluster); return c; } diff --git a/libical/src/libicalss/icaldirset.h b/libical/src/libicalss/icaldirset.h index e9d6240aeb..7d205ecf0a 100644 --- a/libical/src/libicalss/icaldirset.h +++ b/libical/src/libicalss/icaldirset.h @@ -30,7 +30,6 @@ #define ICALDIRSET_H #include "ical.h" -#include "icalerror.h" /* icaldirset Routines for storing, fetching, and searching for ical * objects in a database */ @@ -38,11 +37,11 @@ typedef void icaldirset; -icaldirset* icaldirset_new(char* path); +icaldirset* icaldirset_new(const char* path); void icaldirset_free(icaldirset* store); -char* icaldirset_path(icaldirset* store); +const char* icaldirset_path(icaldirset* store); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately*/ @@ -61,22 +60,21 @@ icalerrorenum icaldirset_select(icaldirset* store, icalcomponent* gauge); void icaldirset_clear(icaldirset* store); /* Get a component by uid */ -icalcomponent* icaldirset_fetch(icaldirset* store, char* uid); -int icaldirset_has_uid(icaldirset* store, char* uid); +icalcomponent* icaldirset_fetch(icaldirset* store, const char* uid); +int icaldirset_has_uid(icaldirset* store, const char* uid); +icalcomponent* icaldirset_fetch_match(icaldirset* set, icalcomponent *c); /* Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ -icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *old, - icalcomponent *new); +icalerrorenum icaldirset_modify(icaldirset* store, icalcomponent *oldc, + icalcomponent *newc); /* Iterate through the components. If a guage has been defined, these will skip over components that do not pass the gauge */ icalcomponent* icaldirset_get_current_component(icaldirset* store); -icalcomponent* icaldirset_get_first_component(icaldirset* store, - icalcomponent_kind kind); -icalcomponent* icaldirset_get_next_component(icaldirset* store, - icalcomponent_kind kind); +icalcomponent* icaldirset_get_first_component(icaldirset* store); +icalcomponent* icaldirset_get_next_component(icaldirset* store); #endif /* !ICALDIRSET_H */ diff --git a/libical/src/libicalss/icalfileset.c b/libical/src/libicalss/icalfileset.c index 46c5cd2586..a7527ff3e0 100644 --- a/libical/src/libicalss/icalfileset.c +++ b/libical/src/libicalss/icalfileset.c @@ -30,7 +30,6 @@ #include "config.h" #endif - #include "icalfileset.h" #include #include /* For PATH_MAX */ @@ -46,21 +45,22 @@ int icalfileset_lock(icalfileset *cluster); int icalfileset_unlock(icalfileset *cluster); - -icalerrorenum icalfileset_create_cluster(char *path); +icalerrorenum icalfileset_create_cluster(const char *path); icalfileset* icalfileset_new_impl() { - struct icalfileset_impl* comp; + struct icalfileset_impl* impl; - if ( ( comp = (struct icalfileset_impl*) + if ( ( impl = (struct icalfileset_impl*) malloc(sizeof(struct icalfileset_impl))) == 0) { icalerror_set_errno(ICAL_NEWFAILED_ERROR); errno = ENOMEM; return 0; } - return comp; + strcpy(impl->id,ICALFILESET_ID); + + return impl; } char* read_from_file(char *s, size_t size, void *d) @@ -69,7 +69,7 @@ char* read_from_file(char *s, size_t size, void *d) return c; } -icalfileset* icalfileset_new(char* path) +icalfileset* icalfileset_new(const char* path) { struct icalfileset_impl *impl = icalfileset_new_impl(); struct stat sbuf; @@ -205,7 +205,7 @@ void icalfileset_free(icalfileset* cluster) free(impl); } -char* icalfileset_path(icalfileset* cluster) +const char* icalfileset_path(icalfileset* cluster) { struct icalfileset_impl *impl = (struct icalfileset_impl*)cluster; icalerror_check_arg_rz((cluster!=0),"cluster"); @@ -250,7 +250,7 @@ int icalfileset_unlock(icalfileset *cluster) } -icalerrorenum icalfileset_create_cluster(char *path) +icalerrorenum icalfileset_create_cluster(const char *path) { FILE* f; @@ -387,11 +387,158 @@ int icalfileset_count_components(icalfileset *cluster, return icalcomponent_count_components(impl->cluster,kind); } -icalerrorenum icalfileset_select(icalfileset* cluster, icalcomponent* gauge); -void icalfileset_clear(icalfileset* cluster); +icalerrorenum icalfileset_select(icalfileset* cluster, icalcomponent* gauge) +{ + assert(0); /* HACK, not implemented */ + return ICAL_NO_ERROR; +} + +void icalfileset_clear(icalfileset* cluster) +{ + assert(0); /* HACK, not implemented */ +} + +icalcomponent* icalfileset_fetch(icalfileset* store,const char* uid) +{ + icalcompiter i; + struct icalfileset_impl* impl = (struct icalfileset_impl*)store; + + for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); + icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ + + icalcomponent *this = icalcompiter_deref(&i); + icalcomponent *inner = icalcomponent_get_first_real_component(this); + icalcomponent *p; + const char *this_uid; + + if(inner != 0){ + p = icalcomponent_get_first_property(inner,ICAL_UID_PROPERTY); + this_uid = icalproperty_get_uid(p); + + if(this_uid==0){ + icalerror_warn("icalfileset_fetch found a component with no UID"); + continue; + } + + if (strcmp(uid,this_uid)==0){ + return this; + } + } + } + + return 0; +} + +int icalfileset_has_uid(icalfileset* store,const char* uid) +{ + assert(0); /* HACK, not implemented */ + return 0; +} + +/******* support routines for icalfileset_fetch_match *********/ + +struct icalfileset_id{ + char* uid; + char* recurrence_id; + int sequence; +}; + +void icalfileset_id_free(struct icalfileset_id *id) +{ + if(id->recurrence_id != 0){ + free(id->recurrence_id); + } + + if(id->uid != 0){ + free(id->uid); + } + +} + +struct icalfileset_id icalfileset_get_id(icalcomponent* comp) +{ + + icalcomponent *inner; + struct icalfileset_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 = strdup(icalvalue_as_ical_string(v)); + + assert(id.recurrence_id != 0); + } + + return id; +} + +/* Find the component that is related to the given + component. Currently, it just matches based on UID and + RECURRENCE-ID */ +icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *comp) +{ + struct icalfileset_impl* impl = (struct icalfileset_impl*)set; + icalcompiter i; + + struct icalfileset_id comp_id, match_id; + + comp_id = icalfileset_get_id(comp); + + for(i = icalcomponent_begin_component(impl->cluster,ICAL_ANY_COMPONENT); + icalcompiter_deref(&i)!= 0; icalcompiter_next(&i)){ + + icalcomponent *match = icalcompiter_deref(&i); + + match_id = icalfileset_get_id(match); + + if(strcmp(comp_id.uid, match_id.uid) == 0 && + ( comp_id.recurrence_id ==0 || + strcmp(comp_id.recurrence_id, match_id.recurrence_id) ==0 )){ + + /* HACK. What to do with SEQUENCE? */ + + icalfileset_id_free(&match_id); + icalfileset_id_free(&comp_id); + return match; + + } + + icalfileset_id_free(&match_id); + } + + icalfileset_id_free(&comp_id); + return 0; + +} + -icalcomponent* icalfileset_fetch(icalfileset* store, char* uid); -int icalfileset_has_uid(icalfileset* store, char* uid); +icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *old, + icalcomponent *new) +{ + assert(0); /* HACK, not implemented */ + return ICAL_NO_ERROR; +} /* Iterate through components */ @@ -405,23 +552,21 @@ icalcomponent* icalfileset_get_current_component (icalfileset* cluster) } -icalcomponent* icalfileset_get_first_component(icalfileset* cluster, - icalcomponent_kind kind) +icalcomponent* icalfileset_get_first_component(icalfileset* cluster) { struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; icalerror_check_arg_rz((cluster!=0),"cluster"); - return icalcomponent_get_first_component(impl->cluster,kind); + return icalcomponent_get_first_component(impl->cluster,ICAL_ANY_COMPONENT); } -icalcomponent* icalfileset_get_next_component(icalfileset* cluster, - icalcomponent_kind kind) +icalcomponent* icalfileset_get_next_component(icalfileset* cluster) { struct icalfileset_impl* impl = (struct icalfileset_impl*)cluster; icalerror_check_arg_rz((cluster!=0),"cluster"); - return icalcomponent_get_next_component(impl->cluster,kind); + return icalcomponent_get_next_component(impl->cluster,ICAL_ANY_COMPONENT); } diff --git a/libical/src/libicalss/icalfileset.h b/libical/src/libicalss/icalfileset.h index 8ceae632be..4430f1dc74 100644 --- a/libical/src/libicalss/icalfileset.h +++ b/libical/src/libicalss/icalfileset.h @@ -40,10 +40,10 @@ typedef void icalfileset; */ -icalfileset* icalfileset_new(char* path); +icalfileset* icalfileset_new(const char* path); void icalfileset_free(icalfileset* cluster); -char* icalfileset_path(icalfileset* cluster); +const char* icalfileset_path(icalfileset* cluster); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately. */ @@ -65,19 +65,22 @@ icalerrorenum icalfileset_select(icalfileset* store, icalcomponent* gauge); void icalfileset_clear(icalfileset* store); /* Get and search for a component by uid */ -icalcomponent* icalfileset_fetch(icalfileset* cluster, char* uid); -int icalfileset_has_uid(icalfileset* cluster, char* uid); +icalcomponent* icalfileset_fetch(icalfileset* cluster, const char* uid); +int icalfileset_has_uid(icalfileset* cluster, const char* uid); +icalcomponent* icalfileset_fetch_match(icalfileset* set, icalcomponent *c); +/* Modify components according to the MODIFY method of CAP. Works on + the currently selected components. */ +icalerrorenum icalfileset_modify(icalfileset* store, icalcomponent *oldcomp, + icalcomponent *newcomp); + /* Iterate through components. If a guage has been defined, these will skip over components that do not pass the gauge */ icalcomponent* icalfileset_get_current_component (icalfileset* cluster); -icalcomponent* icalfileset_get_first_component(icalfileset* cluster, - icalcomponent_kind kind); -icalcomponent* icalfileset_get_next_component(icalfileset* cluster, - icalcomponent_kind kind); - +icalcomponent* icalfileset_get_first_component(icalfileset* cluster); +icalcomponent* icalfileset_get_next_component(icalfileset* cluster); /* Return a reference to the internal component. You probably should not be using this. */ diff --git a/libical/src/libicalss/icalfilesetimpl.h b/libical/src/libicalss/icalfilesetimpl.h index de447c64eb..767dceeadd 100644 --- a/libical/src/libicalss/icalfilesetimpl.h +++ b/libical/src/libicalss/icalfilesetimpl.h @@ -33,7 +33,11 @@ /* This definition is in its own file so it can be kept out of the main header file, but used by "friend classes" like icaldirset*/ +#define ICALFILESET_ID "fset" + struct icalfileset_impl { + + char id[5]; /*fset*/ char *path; icalcomponent* cluster; int changed; diff --git a/libical/src/libicalss/icalgauge.c b/libical/src/libicalss/icalgauge.c index 60ce1587cd..0bbcd20bfc 100644 --- a/libical/src/libicalss/icalgauge.c +++ b/libical/src/libicalss/icalgauge.c @@ -27,6 +27,45 @@ ======================================================================*/ #include "ical.h" +#include "icalgauge.h" +#include "icalgaugeimpl.h" +#include + + +extern char* input_buffer; +extern char* input_buffer_p; +int ssparse(void); + +struct icalgauge_impl *icalss_yy_gauge; + +icalgauge* icalgauge_new_from_sql(char* sql) +{ + struct icalgauge_impl *impl; + + int r; + + if ( ( impl = (struct icalgauge_impl*) + malloc(sizeof(struct icalgauge_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + impl->select = icalcomponent_new(ICAL_XROOT_COMPONENT); + impl->from = icalcomponent_new(ICAL_XROOT_COMPONENT); + impl->where = icalcomponent_new(ICAL_XROOT_COMPONENT); + + icalss_yy_gauge = impl; + + input_buffer_p = input_buffer = sql; + r = ssparse(); + + return impl; +} + + +void icalgauge_free(icalgauge* gauge) +{ +} /* Convert a VQUERY component into a gauge */ icalcomponent* icalgauge_make_gauge(icalcomponent* query); @@ -44,22 +83,18 @@ icalcomponent* icalgauge_make_gauge(icalcomponent* query); When a gauge has several sub-components, the results of testing the target against each of them is ORed together - the target component will pass if it matches any of the sub-components in the - gauge. However, the results of matching the proeprties in a + gauge. However, the results of matching the properties in a sub-component are ANDed -- the target must match every property in a gauge sub-component to match the sub-component. Here is an example: BEGIN:XROOT - BEGIN:VCOMPONENT - BEGIN:VEVENT DTSTART;X-LIC-COMPARETYPE=LESS:19981025T020000 ORGANIZER;X-LIC-COMPARETYPE=EQUAL:mrbig@host.com - END:VEVENT - BEGIN:VEVENT + END:XROOT + BEGIN:XROOT LOCATION;X-LIC-COMPARETYPE=EQUAL:McNary's Pub - END:VEVENT - END:VCALENDAR END:XROOT This gauge has two sub-components; one which will match a VEVENT @@ -194,9 +229,11 @@ int icalgauge_test(icalcomponent* comp, icalerror_check_arg_rz( (comp!=0), "comp"); icalerror_check_arg_rz( (gauge!=0), "gauge"); - for(gauge = icalcomponent_get_first_component(gaugecontainer,ICAL_ANY_COMPONENT); + for(gauge = icalcomponent_get_first_component(gaugecontainer, + ICAL_ANY_COMPONENT); gauge != 0; - gauge = icalcomponent_get_next_component(gaugecontainer,ICAL_ANY_COMPONENT)){ + gauge = icalcomponent_get_next_component(gaugecontainer, + ICAL_ANY_COMPONENT)){ pass += icalgauge_test_recurse(comp, gauge); } diff --git a/libical/src/libicalss/icalgauge.h b/libical/src/libicalss/icalgauge.h index 401d9b7347..2fbb3aab8c 100644 --- a/libical/src/libicalss/icalgauge.h +++ b/libical/src/libicalss/icalgauge.h @@ -29,8 +29,14 @@ #ifndef ICALGAUGE_H #define ICALGAUGE_H -icalcomponent* icalgauge_new_from_vquery(char* vquery); -char* icalgauge_as_vquery(icalcomponent* gauge); +typedef void icalgauge; + +icalgauge* icalgauge_new_from_sql(char* sql); + +void icalgauge_free(icalgauge* gauge); + +char* icalgauge_as_sql(icalcomponent* gauge); + int icalgauge_test(icalcomponent* comp, icalcomponent* gaugecontainer); diff --git a/libical/src/libicalss/icalset.c b/libical/src/libicalss/icalset.c index 01a36c0129..2ffe0deff2 100644 --- a/libical/src/libicalss/icalset.c +++ b/libical/src/libicalss/icalset.c @@ -5,9 +5,9 @@ Icalset is the "base class" for representations of a collection of - iCal components. Derived classes (actually delegatees) include: + iCal components. Derived classes (actually delegates) include: - icalfileset Store componetns in a single file + icalfileset Store components in a single file icaldirset Store components in multiple files in a directory icalheapset Store components on the heap icalmysqlset Store components in a mysql database. @@ -37,49 +37,330 @@ #include "ical.h" #include "icalset.h" #include "icalfileset.h" +#include "icalfilesetimpl.h" #include "icaldirset.h" +#include "icaldirsetimpl.h" +#include /*#include "icalheapset.h"*/ /*#include "icalmysqlset.h"*/ -icalset* icalset_new_file(char* path); +#define ICALSET_ID "set " -icalset* icalset_new_dir(char* path); - -icalset* icalset_new_heap(void); - -icalset* icalset_new_mysql(char* path); - -void icalset_free(icalset* set); +struct icalset_fp { + void (*free)(icalset* set); + const char* (*path)(icalset* set); + void (*mark)(icalset* set); + icalerrorenum (*commit)(icalset* set); + icalerrorenum (*add_component)(icalset* set, icalcomponent* comp); + icalerrorenum (*remove_component)(icalset* set, icalcomponent* comp); + int (*count_components)(icalset* set, + icalcomponent_kind kind); + icalerrorenum (*select)(icalset* set, icalcomponent* gauge); + void (*clear)(icalset* set); + icalcomponent* (*fetch)(icalset* set, const char* uid); + icalcomponent* (*fetch_match)(icalset* set, icalcomponent *comp); + int (*has_uid)(icalset* set, const char* uid); + icalerrorenum (*modify)(icalset* set, icalcomponent *old, + icalcomponent *new); + icalcomponent* (*get_current_component)(icalset* set); + icalcomponent* (*get_first_component)(icalset* set); + icalcomponent* (*get_next_component)(icalset* set); +}; + +struct icalset_fp icalset_dirset_fp = { + icaldirset_free, + icaldirset_path, + icaldirset_mark, + icaldirset_commit, + icaldirset_add_component, + icaldirset_remove_component, + icaldirset_count_components, + icaldirset_select, + icaldirset_clear, + icaldirset_fetch, + icaldirset_fetch_match, + icaldirset_has_uid, + icaldirset_modify, + icaldirset_get_current_component, + icaldirset_get_first_component, + icaldirset_get_next_component +}; + + +struct icalset_fp icalset_fileset_fp = { + icalfileset_free, + icalfileset_path, + icalfileset_mark, + icalfileset_commit, + icalfileset_add_component, + icalfileset_remove_component, + icalfileset_count_components, + icalfileset_select, + icalfileset_clear, + icalfileset_fetch, + icalfileset_fetch_match, + icalfileset_has_uid, + icalfileset_modify, + icalfileset_get_current_component, + icalfileset_get_first_component, + icalfileset_get_next_component +}; + +struct icalset_impl { + + char id[5]; /* "set " */ + + void *derived_impl; + struct icalset_fp *fp; +}; + +/* Figure out what was actually passed in as the set. This could be a + set or and of the derived types such as dirset or fileset. Note + this routine returns a value, not a reference, to avoid memory + leaks in the methods */ +struct icalset_impl icalset_get_impl(icalset* set) +{ + struct icalset_impl impl; + + memset(&impl,0,sizeof(impl)); + icalerror_check_arg_rv( (set!=0),"set"); + + if(strcmp((char*)set,ICALSET_ID)==0) { + /* It is actually a set, so just sent the reference back out. */ + return *(struct icalset_impl*)set; + } else if(strcmp((char*)set,ICALFILESET_ID)==0) { + /* Make a new set from the fileset */ + impl.fp = &icalset_fileset_fp; + impl.derived_impl = set; + strcpy(impl.id,ICALFILESET_ID);/* HACK. Is this necessary? */ + return impl; + } else if(strcmp((char*)set,ICALDIRSET_ID)==0) { + /* Make a new set from the dirset */ + impl.fp = &icalset_dirset_fp; + impl.derived_impl = set; + strcpy(impl.id,ICALDIRSET_ID);/* HACK. Is this necessary? */ + return impl; + } else { + /* The type of set is unknown, so throw an error */ + icalerror_assert((0),"Unknown set type"); + return impl; + } +} + + +struct icalset_impl* icalset_new_impl() +{ + + struct icalset_impl* impl; + + if ( ( impl = (struct icalset_impl*) + malloc(sizeof(struct icalset_impl))) == 0) { + icalerror_set_errno(ICAL_NEWFAILED_ERROR); + return 0; + } + + strcpy(impl->id,ICALSET_ID); + + impl->derived_impl = 0; + impl->fp = 0; + + return impl; +} + +struct icalset_impl* icalset_new_file_from_ref(icalfileset *fset) +{ + struct icalset_impl *impl = icalset_new_impl(); + + icalerror_check_arg_rz( (fset!=0),"fset"); + + if(impl == 0){ + free(impl); + return 0; + } + + impl->derived_impl = fset; + + if (impl->derived_impl == 0){ + free(impl); + return 0; + } + + impl->fp = &icalset_fileset_fp; + + return (struct icalset_impl*)impl; +} + +icalset* icalset_new_file(const char* path) +{ + icalfileset *fset = icalfileset_new(path); + + if(fset == 0){ + return 0; + } + + return (icalset*)icalset_new_file_from_ref(fset); +} + +icalset* icalset_new_dir_from_ref(icaldirset *dset) +{ + + struct icalset_impl *impl = icalset_new_impl(); + + icalerror_check_arg_rz( (dset!=0),"dset"); + + if(impl == 0){ + return 0; + } + + impl->derived_impl = dset; + + if (impl->derived_impl == 0){ + free(impl); + return 0; + } + + impl->fp = &icalset_dirset_fp; + + return impl; +} + +icalset* icalset_new_dir(const char* path) +{ + icaldirset *dset = icaldirset_new(path); + + if(dset == 0){ + return 0; + } + + return icalset_new_dir_from_ref(dset); +} + +icalset* icalset_new_heap(void) +{ + struct icalset_impl *impl = icalset_new_impl(); -char* icalset_path(icalset* set); -void icalset_mark(icalset* set); + if(impl == 0){ + free(impl); + return 0; + } -icalerrorenum icalset_commit(icalset* set); + return 0; +} -icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp); +icalset* icalset_new_mysql(const char* path) +{ + struct icalset_impl *impl = icalset_new_impl(); -icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp); + if(impl == 0){ + free(impl); + return 0; + } -int icalset_count_components(icalset* set, - icalcomponent_kind kind); + return 0; +} -icalerrorenum icalset_select(icalset* set, icalcomponent* gauge); +void icalset_free(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->free))(impl.derived_impl); -void icalset_clear_select(icalset* set); + if(strcmp((char*)set,ICALSET_ID)) { + free(set); + } +} -icalcomponent* icalset_fetch(icalset* set, char* uid); +const char* icalset_path(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->path))(impl.derived_impl); +} -int icalset_has_uid(icalset* set, char* uid); +void icalset_mark(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->mark))(impl.derived_impl); +} + +icalerrorenum icalset_commit(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->commit))(impl.derived_impl); +} + +icalerrorenum icalset_add_component(icalset* set, icalcomponent* comp) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->add_component))(impl.derived_impl,comp); +} + +icalerrorenum icalset_remove_component(icalset* set, icalcomponent* comp) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->remove_component))(impl.derived_impl,comp); +} + +int icalset_count_components(icalset* set,icalcomponent_kind kind) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->count_components))(impl.derived_impl,kind); +} + +icalerrorenum icalset_select(icalset* set, icalcomponent* gauge) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->select))(impl.derived_impl,gauge); +} + +void icalset_clear(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->clear))(impl.derived_impl); +} + +icalcomponent* icalset_fetch(icalset* set, const char* uid) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->fetch))(impl.derived_impl,uid); +} + +icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *comp) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->fetch_match))(impl.derived_impl,comp); +} + + +int icalset_has_uid(icalset* set, const char* uid) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->has_uid))(impl.derived_impl,uid); +} icalerrorenum icalset_modify(icalset* set, icalcomponent *old, - icalcomponent *new); - -icalcomponent* icalset_get_current_component(icalset* set); - -icalcomponent* icalset_get_first_component(icalset* set); - -icalcomponent* icalset_get_next_component(icalset* set); + icalcomponent *new) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->modify))(impl.derived_impl,old,new); +} + +icalcomponent* icalset_get_current_component(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->get_current_component))(impl.derived_impl); +} + +icalcomponent* icalset_get_first_component(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->get_first_component))(impl.derived_impl); +} + +icalcomponent* icalset_get_next_component(icalset* set) +{ + struct icalset_impl impl = icalset_get_impl(set); + return (*(impl.fp->get_next_component))(impl.derived_impl); +} diff --git a/libical/src/libicalss/icalset.h b/libical/src/libicalss/icalset.h index 15bb71f72e..d4678e3bed 100644 --- a/libical/src/libicalss/icalset.h +++ b/libical/src/libicalss/icalset.h @@ -52,15 +52,15 @@ typedef enum icalset_kind { /* Create a specific derived type of set */ -icalset* icalset_new_file(char* path); -icalset* icalset_new_dir(char* path); +icalset* icalset_new_file(const char* path); +icalset* icalset_new_dir(const char* path); icalset* icalset_new_heap(void); -icalset* icalset_new_mysql(char* path); +icalset* icalset_new_mysql(const char* path); /*icalset* icalset_new_cap(icalcstp* cstp);*/ void icalset_free(icalset* set); -char* icalset_path(icalset* set); +const char* icalset_path(icalset* set); /* Mark the cluster as changed, so it will be written to disk when it is freed. Commit writes to disk immediately*/ @@ -79,13 +79,14 @@ icalerrorenum icalset_select(icalset* set, icalcomponent* gauge); void icalset_clear_select(icalset* set); /* Get a component by uid */ -icalcomponent* icalset_fetch(icalset* set, char* uid); -int icalset_has_uid(icalset* set, char* uid); +icalcomponent* icalset_fetch(icalset* set, const char* uid); +int icalset_has_uid(icalset* set, const char* uid); +icalcomponent* icalset_fetch_match(icalset* set, icalcomponent *c); /* Modify components according to the MODIFY method of CAP. Works on the currently selected components. */ -icalerrorenum icalset_modify(icalset* set, icalcomponent *old, - icalcomponent *new); +icalerrorenum icalset_modify(icalset* set, icalcomponent *oldc, + icalcomponent *newc); /* Iterate through the components. If a guage has been defined, these will skip over components that do not pass the gauge */ diff --git a/libical/src/libicalvcal/icalvcal.c b/libical/src/libicalvcal/icalvcal.c index d21dd4acc6..9ae00a7d90 100644 --- a/libical/src/libicalvcal/icalvcal.c +++ b/libical/src/libicalvcal/icalvcal.c @@ -20,6 +20,23 @@ The original code is icalvcal.c + + + The icalvcal_convert routine calls icalvcal_traverse_objects to do + its work.s his routine steps through through all of the properties + and components of a VObject. For each name of a property or a + component, icalvcal_traverse_objects looks up the name in + conversion_table[]. This table indicates wether the name is of a + component or a property, lists a routine to handle conversion, and + has extra data for the conversion. + + The conversion routine will create new iCal components or properties + and add them to the iCal component structure. + + The most common conversion routine is dc_prop. This routine converts + properties for which the text representation of the vCal component + is identical the iCal representation. + ======================================================================*/ #include "icalvcal.h" @@ -43,7 +60,7 @@ struct conversion_table_struct { struct conversion_table_struct conversion_table[]; void* dc_prop(int icaltype, VObject *object); -static void traverse_objects(VObject *object,icalcomponent* last_comp, +static void icalvcal_traverse_objects(VObject *object,icalcomponent* last_comp, icalproperty* last_prop) { VObjectIterator iterator; @@ -66,6 +83,8 @@ static void traverse_objects(VObject *object,icalcomponent* last_comp, } } + /* Did not find the object. It may be an X-property, or an unknown + property */ if (conversion_table[i].vcalname == 0){ /* Handle X properties */ @@ -158,10 +177,10 @@ static void traverse_objects(VObject *object,icalcomponent* last_comp, should use it as the 'last_comp' */ if(subc!=0){ - traverse_objects(eachProp,subc,last_prop); + icalvcal_traverse_objects(eachProp,subc,last_prop); } else { - traverse_objects(eachProp,last_comp,last_prop); + icalvcal_traverse_objects(eachProp,last_comp,last_prop); } } } @@ -180,7 +199,7 @@ icalcomponent* icalvcal_convert(VObject *object){ } - traverse_objects(object,container,0); + icalvcal_traverse_objects(object,container,0); /* HACK. I am using the extra 'container' component because I am lazy. I know there is a way to get rid of it, but I did not care diff --git a/libical/src/test/recur.c b/libical/src/test/recur.c index 4d3188f9c2..2967ee7977 100644 --- a/libical/src/test/recur.c +++ b/libical/src/test/recur.c @@ -52,11 +52,9 @@ int main(int argc, char *argv[]) cin = icalfileset_new(argv[1]); assert(cin != 0); - for (itr = icalfileset_get_first_component(cin, - ICAL_ANY_COMPONENT); + for (itr = icalfileset_get_first_component(cin); itr != 0; - itr = icalfileset_get_next_component(cin, - ICAL_ANY_COMPONENT)){ + itr = icalfileset_get_next_component(cin)){ desc = icalcomponent_get_first_property(itr,ICAL_DESCRIPTION_PROPERTY); assert(desc !=0); diff --git a/libical/src/test/testmime.c b/libical/src/test/testmime.c index a912983f84..5dfc3b7d31 100644 --- a/libical/src/test/testmime.c +++ b/libical/src/test/testmime.c @@ -86,6 +86,7 @@ char* read_stream(char *s, size_t size, void *d) } + int main(int argc, char* argv[]) { FILE *f; @@ -135,7 +136,7 @@ int main(int argc, char* argv[]) { opt.stress = 1; break; } - case 'b':{ /* test base64 encoding*/ + case 'b':{ /* test base64 decoding*/ if(opt.stress+opt.normal+opt.qp != 0){ fprintf(stderr, "%s: Use only one of n,s,b and q\n", @@ -144,7 +145,7 @@ int main(int argc, char* argv[]) { opt.base64 = 1; break; } - case 'q':{ /* test quoted-printable encoding*/ + case 'q':{ /* test quoted-printable decoding*/ if(opt.stress+opt.base64+opt.normal != 0){ fprintf(stderr, "%s: Use only one of n,s,b and q\n", -- cgit v1.2.3