void ical_property_DTSTAMP(struct exchange2ical *exchange2ical)
{
	icalproperty		*prop;
	struct icaltimetype	icaltime;
	struct tm		*tm;
	icalparameter		*tzid;
	time_t			t;

	/* Sanity check */
	/*If OwnerCriticalChange field is null, get time system time*/
	if (!exchange2ical->OwnerCriticalChange) {
		t=time(NULL);
		tm = gmtime(&t);
		icaltime = get_icaltimetype_from_tm_UTC(tm);
		prop = icalproperty_new_dtstamp(icaltime);
		icalcomponent_add_property(exchange2ical->vevent, prop);
		return;
	} else {
	      icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->OwnerCriticalChange);
	      prop = icalproperty_new_dtstamp(icaltime);
	      icalcomponent_add_property(exchange2ical->vevent, prop);
	      if (exchange2ical->TimeZoneDesc) {
			tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
			icalproperty_add_parameter(prop, tzid);
		}
	}
}
void ical_property_DTEND(struct exchange2ical *exchange2ical)
{
	icalproperty		*prop;
	icalparameter		*tzid;
	struct icaltimetype	icaltime;

	/* Sanity check */
	if (!exchange2ical->apptEndWhole) return;

	/* If this is an all-day appointment */
	if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
		icaltime = get_icaldate_from_FILETIME(exchange2ical->apptEndWhole);
		prop = icalproperty_new_dtend(icaltime);
		icalcomponent_add_property(exchange2ical->vevent, prop);
	} else {
		if (exchange2ical->TimeZoneDesc) {
			icaltime = get_icaltime_from_FILETIME(exchange2ical->apptEndWhole);
			prop = icalproperty_new_dtend(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
			tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
			icalproperty_add_parameter(prop, tzid);
		} else {
			icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptEndWhole);
			prop = icalproperty_new_dtend(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		}
		
	}
}
void ical_property_LAST_MODIFIED(struct exchange2ical *exchange2ical)
{
	icalproperty		*prop;
	struct icaltimetype	icaltime;
	icalparameter		*tzid;


	/* Sanity check */
	if (!exchange2ical->LastModified) return;
	if (exchange2ical->TimeZoneDesc) {
		icaltime=get_icaltime_from_FILETIME(exchange2ical->LastModified);
		prop = icalproperty_new_lastmodified(icaltime);
		tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
		icalproperty_add_parameter(prop, tzid);
	} else {
		icaltime=get_icaltime_from_FILETIME_UTC(exchange2ical->LastModified);
		prop = icalproperty_new_lastmodified(icaltime);
	}
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
void ical_property_RECURRENCE_ID(struct exchange2ical *exchange2ical)
{	
	struct icaltimetype	icaltime;
	icalproperty 		*prop;
	icalparameter		*tzid;
	struct GlobalObjectId	*GlbObjId;

	
	if (exchange2ical->ExceptionReplaceTime){
		/*if parent has an all day event*/
 		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			icaltime = get_icaldate_from_FILETIME(exchange2ical->ExceptionReplaceTime);
			prop = icalproperty_new_recurrenceid(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		} else {
			if (exchange2ical->TimeZoneDesc) {
				icaltime=get_icaltime_from_FILETIME(exchange2ical->ExceptionReplaceTime);
				prop = icalproperty_new_recurrenceid(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, tzid);
			} else {
				icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->ExceptionReplaceTime);
				prop = icalproperty_new_recurrenceid(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}
	} else if (exchange2ical->GlobalObjectId){
		GlbObjId = get_GlobalObjectId(exchange2ical->mem_ctx, exchange2ical->GlobalObjectId);
		if(GlbObjId){
			icaltime=get_icaldate_from_GlobalObjectId(GlbObjId);
			prop = icalproperty_new_recurrenceid(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
			talloc_free(GlbObjId);

		}
	}
	
}
示例#5
0
void add_class(icalcomponent* calendar, vector<string>& classes)
{
  cout << "What is the name of the class?" << endl;
  string class_name;
  cin >> class_name;
  classes.push_back(class_name);
  
  
  //List each property field one at a time
  string all_props[] = {"ATTACH", "ATTENDEE", "CATEGORIES", "CLASS", "COMMENT", "CONTACT", "CREATED", "DESCRIPTION", "DTEND", "DTSTAMP", "DTSTART", "DURATION", "EXDATE", "EXRULE", "GEO", "LAST-MOD", "LOCATION", "ORGANIZER", "PRIORITY", "RDATE", "RECURID", "RELATED", "RESOURCES", "RRULE", "RSTATUS", "SEQ", "STATUS", "SUMMARY", "TRANSP", "UID", "URL"};
  
  //FIXME Start/end dates rely on default start/end of semester if user okays default
  
  vector<string> values;
  
  for (int i = 0; i < 31; i++)
  {
    cout << all_props[i] << ": ";
    std::flush(cout);
    
    string value = "";
    getline(cin, value);
    
    if (cin.fail())
    {
      throw cin_fail_ex;
    }

    //FIXME Take user input and validate 
    values.push_back(value);
    cout << endl;
  }
   
  struct icaltimetype atime = icaltime_from_timet(time(0), 0);
  
  //Add the values to the event
  icalcomponent* class_event = icalcomponent_vanew(
		ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstamp(atime),
    icalproperty_new_contact(values[5].c_str()),
    icalproperty_new_comment(values[4].c_str()),
    icalproperty_vanew_attach(
      NULL, //FIXME icalattach *icalattach_new_from_url (const char *url);
      values[0].c_str(),  //FIXME?
      0
      ),
    //FIXME icalproperty_new_duration(values[11].c_str()), //needs right type
    //FIXME icalproperty_new_exdate(values[13].c_str()),  //needs struct icaltimetype v
    //FIXME icalproperty_new_geo(values[14].c_str()), //needs right type
    //FIXME icalproperty_new_lastmodified(values[15].c_str()),
    icalproperty_new_priority(atoi(values[18].c_str())),
    //FIXME icalproperty_vanew_recurid(),
    //FIXME icalproperty_vanew_related(),
    //FIXME icalproperty_vanew_resources(),
    //FIXME icalproperty_vanew_sequence(),
    //FIXME icalproperty_new_rrule(values[23].c_str()),
    //FIXME icalproperty_new_status(values[26].c_str()),
    //FIXME icalproperty_new_rstatus()  may not exist...
    /*FIXME icalproperty_vanew_rdate(
      values[15].c_str(),
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),*/
    /*FIXME icalproperty_vanew_exdate(  //FIXME exceptions to recurrences
      values[12].c_str(), //FIXME struct icaltimetype v
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),*/
    icalproperty_new_transp(ICAL_TRANSP_NONE), //FIXME values[28]... This is a six-way selector between ICAL_TRANSP_X, ICAL_TRANSP_OPAQUE, ICAL_TRANSP_OPAQUENOCONFLICT, ICAL_TRANSP_TRANSPARENT,  ICAL_TRANSP_TRANSPARENTNOCONFLICT, ICAL_TRANSP_NONE... Relates to free/busy conflicts
		icalproperty_new_uid(values[29].c_str()),
    icalproperty_new_url(values[30].c_str()),
		icalproperty_vanew_organizer(
		    values[17].c_str(),
		    icalparameter_new_role(ICAL_ROLE_CHAIR),
		    0
		    ),
		icalproperty_vanew_attendee(
      values[1].c_str(),
      icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),  //FIXME overwrites user settings. Either ICAL_ROLE_REQPARTICIPANT, ICAL_ROLE_OPTPARTICIPANT, ICAL_ROLE_NONPARTICIPANT
      //FIXME icalparameter_new_rsvp(1),  //FIXME overwrites user settings
      icalparameter_new_cutype(ICAL_CUTYPE_GROUP),  //FIXME overwrites user settings. Type of calendar user specified by property?
      0
      ),
		icalproperty_new_description(values[7].c_str()),

		icalproperty_new_categories(values[2].c_str()),
		icalproperty_new_class(ICAL_CLASS_PUBLIC),  //FIXME overwrites user settings
		icalproperty_new_created(atime),  //FIXME overwrites user settings
		icalproperty_new_summary(values[27].c_str()),
		icalproperty_vanew_dtstart(
      atime,                  //FIXME overwrites user settings
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),
		icalproperty_vanew_dtend(
      atime,                //FIXME overwrites user settings
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),
		icalproperty_new_location(values[16].c_str()),
		0
		);  
  
  //FIXME Handle alarm threads (to be implemented later)
 
  //Add the class component to calendar
  icalcomponent_add_component(calendar, class_event);
  
  append_action_to_closed_log("Add Class", true);
}
示例#6
0
void add_event(icalcomponent* calendar)
{
  string class_name;

  //Ask if the event is for a class
  bool is_class_event = yes_no_prompt("Is this event for a class? (y/n)");
  
  //FIXME Following not implemented in this sprint
  if (is_class_event)
  {
    //FIXME If event for class, make sure the semester is not over
    //FIXME If the semester is over, notify the user
    
    //If event for class, prompt for class id
    cout << "What is the name of this class?" << endl;
    cin >> class_name;
  }
    
    
  //List each property field one at a time
  cout << "Enter information for each of the following properties." << endl;
  string all_props[] = {"ATTACH", "ATTENDEE", "CATEGORIES", "CLASS", "COMMENT", "CONTACT", "CREATED", "DESCRIPTION", "DTEND", "DTSTAMP", "DTSTART", "DURATION", "EXDATE", "EXRULE", "GEO", "LAST-MOD", "LOCATION", "ORGANIZER", "PRIORITY", "RDATE", "RECURID", "RELATED", "RESOURCES", "RRULE", "RSTATUS", "SEQ", "STATUS", "SUMMARY", "TRANSP", "UID", "URL"};
  
  vector<string> values;
  
  for (int i = 0; i < 31; i++)
  {
    cout << all_props[i] << ": ";
    flush(cout);
    
    string value = "";
    getline(cin, value); //FIXME Check for failbit
    
    //FIXME Take user input and validate 
    values.push_back(value);
    cout << endl;
  }
  
  //If event for class, add property X-CLASS
  string value = "";
  if (is_class_event)
  {
    cout << "X-CLASS: ";
    flush(cout);
      
    getline(cin, value); //FIXME Check for failbit
    //FIXME Take user input and validate
    values.push_back(value);
      
    cout << endl;
  }
  
  struct icaltimetype atime = icaltime_from_timet(time(0), 0);
  
  //Add the values to the event
  icalcomponent* event = icalcomponent_vanew(
		ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstamp(atime),
    icalproperty_new_contact(values[5].c_str()),
    icalproperty_new_comment(values[4].c_str()),
    icalproperty_vanew_attach(
      NULL, //FIXME is this the file encoding?
      values[0].c_str(),
      0
      ),
    //FIXME icalproperty_new_duration(values[11].c_str()),
    //FIXME icalproperty_new_exdate(values[13].c_str()),
    //FIXME icalproperty_new_geo(values[14].c_str()),
    //FIXME icalproperty_new_lastmod(values[15].c_str()),
    icalproperty_new_priority(atoi(values[18].c_str())),
    //FIXME icalproperty_vanew_recurid(),
    //FIXME icalproperty_vanew_related(),
    //FIXME icalproperty_vanew_resources(),
    //FIXME icalproperty_vanew_sequence(),
    //FIXME icalproperty_new_rrule(values[23].c_str()),
    //FIXME icalproperty_new_status(values[26].c_str()),
    //FIXME icalproperty_new_rstatus()  may not exist...
    /*FIXME icalproperty_vanew_rdate(
      values[15].c_str(),
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),*/
    /*FIXME icalproperty_vanew_exdate(
      values[12].c_str(),
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),*/
    //FIXME icalproperty_new_transp(values[28].c_str()),
		icalproperty_new_uid(values[29].c_str()),
    icalproperty_new_url(values[30].c_str()),
		icalproperty_vanew_organizer(
		    values[17].c_str(),
		    icalparameter_new_role(ICAL_ROLE_CHAIR),  //FIXME overwrites user settings
		    0
		    ),
		icalproperty_vanew_attendee(
      values[1].c_str(),
      icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),  //FIXME overwrites user settings
      //FIXME icalparameter_new_rsvp(1),  //FIXME overwrites user settings
      icalparameter_new_cutype(ICAL_CUTYPE_GROUP),  //FIXME overwrites user settings
      0
      ),
		icalproperty_new_description(values[7].c_str()),

		icalproperty_new_categories(values[2].c_str()),
		icalproperty_new_class(ICAL_CLASS_PUBLIC),  //FIXME overwrites user settings
		icalproperty_new_created(atime),  //FIXME overwrites user settings
		icalproperty_new_summary(values[27].c_str()),
		icalproperty_vanew_dtstart(
      atime,                  //FIXME overwrites user settings
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),
		icalproperty_vanew_dtend(
      atime,                //FIXME overwrites user settings
      icalparameter_new_tzid("US-Central"), //FIXME should get timezone from user
      0
      ),
		icalproperty_new_location(values[16].c_str()),
		0
		);  
  
  if (is_class_event)
  {
    icalproperty* p;
    icalproperty_set_x(p, value.c_str());
    icalcomponent_add_property(event, p);
  }
  
  //Add component event to calendar
  icalcomponent_add_component(calendar,event);
  
  //FIXME Handle alarm threads (to be implemented later)
  
  append_action_to_closed_log("Add Event", true);
}
示例#7
0
static uint8_t exchange2ical_exception_from_ExceptionInfo(struct exchange2ical *exchange2ical, struct exchange2ical_check *exchange2ical_check)
{
	uint32_t	i;
	icalproperty *prop;
	icalparameter *param;
	icaltimetype icaltime;
	/*sanity checks*/
	if(!exchange2ical->AppointmentRecurrencePattern) return 1;
	if(!exchange2ical->AppointmentRecurrencePattern->ExceptionInfo) return 1;
	if(!exchange2ical->AppointmentRecurrencePattern->ExceptionCount) return 1;

	for(i=0; i<exchange2ical->AppointmentRecurrencePattern->ExceptionCount; i++) {
		
		/*Check to see if event is acceptable*/
		struct tm apptStart=get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
		if (!checkEvent(exchange2ical, exchange2ical_check, &apptStart)){
			return 0;
		}
		
		/*Create a new vevent*/
		exchange2ical->vevent = icalcomponent_new_vevent();
		if ( ! (exchange2ical->vevent) ) {
			return 1;
		}
		icalcomponent_add_component(exchange2ical->vcalendar, exchange2ical->vevent);

		/*dtstart from StartDateTime*/
		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
			icaltime= get_icaldate_from_tm(&tm);
			prop = icalproperty_new_dtstart(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		}else {
			if(exchange2ical->TimeZoneDesc){
				struct tm	tm;
				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_dtstart(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, param);
			} else {
				struct tm	tm;
				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->StartDateTime);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_dtstart(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}
		/*dtend from EndDateTime*/
		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
			icaltime= get_icaldate_from_tm(&tm);
			prop = icalproperty_new_dtend(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		}else {
			if(exchange2ical->TimeZoneDesc){
				struct tm	tm;
				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_dtend(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, param);
			} else {
				struct tm	tm;
				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->EndDateTime);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_dtend(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}
		/*recurrence-id from OriginalStartDate*/
		if (exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
			icaltime= get_icaldate_from_tm(&tm);
			prop = icalproperty_new_recurrenceid(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		}else {
			if(exchange2ical->TimeZoneDesc){
				struct tm	tm;
				tm = get_tm_from_minutes(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_recurrenceid(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				param = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, param);
			} else {
				struct tm	tm;
				tm = get_tm_from_minutes_UTC(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OriginalStartDate);
				icaltime= get_icaldate_from_tm(&tm);
				prop = icalproperty_new_recurrenceid(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}
		
		/*summary from Subject if subject is set*/
		if (exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0001) {
			exchange2ical->Subject=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Subject.subjectMsg.msg;
			ical_property_SUMMARY(exchange2ical);
		}
		

		/*Valarm*/
		/*ReminderSet*/
		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0008){
			exchange2ical->ReminderSet=(uint8_t *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rSet;
			/*Reminder Delta*/
			if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0004){
				exchange2ical->ReminderDelta=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->ReminderDelta.rDelta;
			} else {
				exchange2ical->ReminderDelta=NULL;
			}
			ical_component_VALARM(exchange2ical);
		}

		/*Location*/
		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0010){
			exchange2ical->Location=(const char *) &exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->Location.locationMsg.msg;
			ical_property_LOCATION(exchange2ical);
		}
		
		/*Busy Status*/
		if(exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->OverrideFlags & 0x0020){
			exchange2ical->BusyStatus=&exchange2ical->AppointmentRecurrencePattern->ExceptionInfo->BusyStatus.bStatus;
			ical_property_X_MICROSOFT_CDO_BUSYSTATUS(exchange2ical);
		}
	}
	return 0;
}
icalcomponent* create_new_component()
{

    /* variable definitions */
    icalcomponent* calendar;
    icalcomponent* event;
    struct icaltimetype atime = icaltime_from_timet( time(0),0);
    struct icalperiodtype rtime;
    icalproperty* property;

    /* Define a time type that will use as data later. */
    rtime.start = icaltime_from_timet( time(0),0);
    rtime.end = icaltime_from_timet( time(0),0);
    rtime.end.hour++;

    /* Create calendar and add properties */

    calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);
    
    /* Nearly every libical function call has the same general
       form. The first part of the name defines the 'class' for the
       function, and the first argument will be a pointer to a struct
       of that class. So, icalcomponent_ functions will all take
       icalcomponent* as their first argument. */

    /* The next call creates a new proeprty and immediately adds it to the 
       'calendar' component. */ 

    icalcomponent_add_property(
	calendar,
	icalproperty_new_version("2.0")
	);

    
    /* Here is the short version of the memory rules: 

         If the routine name has "new" in it: 
	     Caller owns the returned memory. 
             If you pass in a string, the routine takes the memory. 	 

         If the routine name has "add" in it:
	     The routine takes control of the component, property, 
	     parameter or value memory.

         If the routine returns a string ( "get" and "as_ical_string" )
	     The library owns the returned memory. 

	  There are more rules, so refer to the documentation for more 
	  details. 

    */

    icalcomponent_add_property(
	calendar,
	icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN")
	);
    
    /* Add an event */

    event = icalcomponent_new(ICAL_VEVENT_COMPONENT);

    icalcomponent_add_property(
	event,
	icalproperty_new_dtstamp(atime)
	);

    /* In the previous call, atime is a struct, and it is passed in by value. 
       This is how all compound types of values are handled. */

    icalcomponent_add_property(
	event,
	icalproperty_new_uid("guid-1.host1.com")
	);

    /* add a property that has parameters */
    property = icalproperty_new_organizer("mailto:[email protected]");
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_role(ICAL_ROLE_CHAIR)
	);

    icalcomponent_add_property(event,property);

    /* In this style of component creation, you need to use an extra
       call to add parameters to properties, but the form of this
       operation is the same as adding a property to a component */

    /* add another property that has parameters */
    property = icalproperty_new_attendee("mailto:[email protected]");
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT)
	);

    icalproperty_add_parameter(
	property,
	icalparameter_new_rsvp(1)
	);

    icalproperty_add_parameter(
	property,
	icalparameter_new_cutype(ICAL_CUTYPE_GROUP)
	);

    icalcomponent_add_property(event,property);


    /* more properties */

    icalcomponent_add_property(
	event,
	icalproperty_new_description("Project XYZ Review Meeting")
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_categories("MEETING")
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_class(ICAL_CLASS_PUBLIC)
	);
    
    icalcomponent_add_property(
	event,
	icalproperty_new_created(atime)
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_summary("XYZ Project Review")
	);

    property = icalproperty_new_dtstart(atime);
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_tzid("US-Eastern")
	);

    icalcomponent_add_property(event,property);


    property = icalproperty_new_dtend(atime);
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_tzid("US-Eastern")
	);

    icalcomponent_add_property(event,property);

    icalcomponent_add_property(
	event,
	icalproperty_new_location("1CP Conference Room 4350")
	);

    icalcomponent_add_component(calendar,event);

    return calendar;
}
icalcomponent* create_new_component_with_va_args()
{

    /* This is a similar set up to the last routine */
    icalcomponent* calendar;
    struct icaltimetype atime = icaltime_from_timet( time(0),0);
    struct icalperiodtype rtime;
    
    rtime.start = icaltime_from_timet( time(0),0);
    rtime.end = icaltime_from_timet( time(0),0);
    rtime.end.hour++;

    /* Some of these routines are the same as those in the previous
       routine, but we've also added several 'vanew' routines. These
       'vanew' routines take a list of properties, parameters or
       values and add each of them to the parent property or
       component. */

    calendar = 
	icalcomponent_vanew(
	    ICAL_VCALENDAR_COMPONENT,
	    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("guid-1.host1.com"),
		icalproperty_vanew_organizer(
		    "mailto:[email protected]",
		    icalparameter_new_role(ICAL_ROLE_CHAIR),
		    0
		    ),
		icalproperty_vanew_attendee(
		    "mailto:[email protected]",
		    icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),
		    icalparameter_new_rsvp(1),
		    icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
		    0
		    ),
		icalproperty_new_description("Project XYZ Review Meeting"),

		icalproperty_new_categories("MEETING"),
		icalproperty_new_class(ICAL_CLASS_PUBLIC),
		icalproperty_new_created(atime),
		icalproperty_new_summary("XYZ Project Review"),
		icalproperty_vanew_dtstart(
		    atime,
		    icalparameter_new_tzid("US-Eastern"),
		    0
		    ),
		icalproperty_vanew_dtend(
		    atime,
		    icalparameter_new_tzid("US-Eastern"),
		    0
		    ),
		icalproperty_new_location("1CP Conference Room 4350"),
		0
		),
	    0
	    );

   
    /* Note that properties with no parameters can use the regular
       'new' constructor, while those with parameters use the 'vanew'
       constructor. And, be sure that the last argument in the 'vanew'
       call is a zero. Without, your program will probably crash. */

    return calendar;
}
/* Create a new component */
void create_new_component()
{
    icalcomponent* calendar;
    icalcomponent* timezone;
    icalcomponent* tzc;
    icalcomponent* event;
    struct icaltimetype atime = icaltime_from_timet( 1023398689, 0);
    struct icaldatetimeperiodtype rtime;
    icalproperty* property;
    char *calendar_as_string;

    rtime.period.start = icaltime_from_timet( 1023398689,0);
    rtime.period.end = icaltime_from_timet( 1023409689,0);
    rtime.period.end.hour++;
    rtime.time = icaltime_null_time();

    /* Create calendar and add properties */
    calendar = icalcomponent_new(ICAL_VCALENDAR_COMPONENT);

    
    icalcomponent_add_property(
	calendar,
	icalproperty_new_version("2.0")
	);
    
    icalcomponent_add_property(
	calendar,
	icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN")
	);
    
    /* Create a timezone object and add it to the calendar */

    timezone = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);

    icalcomponent_add_property(
	timezone,
	icalproperty_new_tzid("America/New_York")
	);

    /* Add a sub-component of the timezone */
    tzc = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_dtstart(atime)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_rdate(rtime)
	);
	    
    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzoffsetfrom(-5*3600)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzoffsetto(-4*3600)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzname("EST")
	);

    icalcomponent_add_component(timezone,tzc);

    icalcomponent_add_component(calendar,timezone);

    /* Add a second subcomponent */
    tzc = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_dtstart(atime)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_rdate(rtime)
	);
	    
    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzoffsetfrom(-4*3600)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzoffsetto(-5*3600)
	);

    icalcomponent_add_property(
	tzc, 
	icalproperty_new_tzname("EST")
	);

    icalcomponent_add_component(timezone,tzc);

    /* Add an event */

    event = icalcomponent_new(ICAL_VEVENT_COMPONENT);

    icalcomponent_add_property(
	event,
	icalproperty_new_dtstamp(atime)
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_uid("guid-1.host1.com")
	);

    /* add a property that has parameters */
    property = icalproperty_new_organizer("*****@*****.**");
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_role(ICAL_ROLE_CHAIR)
	);

    icalcomponent_add_property(event,property);

    /* add another property that has parameters */
    property = icalproperty_new_attendee("*****@*****.**");
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT)
	);

    icalproperty_add_parameter(
	property,
	icalparameter_new_rsvp(ICAL_RSVP_TRUE)
	);

    icalproperty_add_parameter(
	property,
	icalparameter_new_cutype(ICAL_CUTYPE_GROUP)
	);

    icalcomponent_add_property(event,property);


    /* more properties */

    icalcomponent_add_property(
	event,
	icalproperty_new_description("Project XYZ Review Meeting")
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_categories("MEETING")
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_class(ICAL_CLASS_PRIVATE)
	);
    
    icalcomponent_add_property(
	event,
	icalproperty_new_created(atime)
	);

    icalcomponent_add_property(
	event,
	icalproperty_new_summary("XYZ Project Review")
	);


    property = icalproperty_new_dtstart(atime);
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_tzid("America/New_York")
	);

    icalcomponent_add_property(event,property);


    property = icalproperty_new_dtend(atime);
    
    icalproperty_add_parameter(
	property,
	icalparameter_new_tzid("America/New_York")
	);

    icalcomponent_add_property(event,property);

    icalcomponent_add_property(
	event,
	icalproperty_new_location("1CP Conference Room 4350")
	);

    icalcomponent_add_component(calendar,event);
    
    calendar_as_string = icalcomponent_as_ical_string(calendar);

    is("build large, complex component", 
       calendar_as_string,
       create_new_component_str);

    if (VERBOSE && calendar)
      printf("%s\n",icalcomponent_as_ical_string(calendar));


    if (calendar)
      icalcomponent_free(calendar);

}
/** Test icalcomponent_get_span()
 *
 */
void test_icalcomponent_get_span()
{
    time_t tm1 = 973378800; /*Sat Nov  4 23:00:00 UTC 2000,
			      Sat Nov  4 15:00:00 PST 2000 */
    time_t tm2 = 973382400; /*Sat Nov  5 00:00:00 UTC 2000 
			      Sat Nov  4 16:00:00 PST 2000 */
    struct icaldurationtype dur;
    struct icaltime_span span;
    icalcomponent *c;
    icaltimezone *azone, *bzone; 
    int	tnum = 0;

    /** test 0
     *	Direct assigning time_t means they will be interpreted as UTC
     */
    span.start = tm1;
    span.end = tm2;
    if (VERBOSE) print_span(tnum++,span);

    /** test 1
     *	We specify times in a timezone, the returned span is in UTC
     */
    azone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_vanew_dtstart(
		    icaltime_from_timet_with_zone(tm1,0,azone),
		    icalparameter_new_tzid("America/Los_Angeles"),0),
		icalproperty_vanew_dtend(
		    icaltime_from_timet_with_zone(tm2,0,azone),
		    icalparameter_new_tzid("America/Los_Angeles"),0),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("America/Los_Angeles", span.start, 973407600);
    icalcomponent_free(c);

    /** test 2
     *	We specify times as floating, the returned span is in UTC
     *	with no conversion applied - so result should be as test 0
     */
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
	    icalproperty_vanew_dtstart(icaltime_from_timet(tm1,0),0),
	    icalproperty_vanew_dtend(icaltime_from_timet(tm2,0),0),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("floating time", span.start, tm1);

    icalcomponent_free(c);

    /** test 3
     *	We specify times in a timezone, the returned span is in UTC
     */
    azone = icaltimezone_get_builtin_timezone("America/New_York");
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_vanew_dtstart(
		    icaltime_from_timet_with_zone(tm1,0,azone),
		    icalparameter_new_tzid("America/New_York"),0),
		icalproperty_vanew_dtend(
		    icaltime_from_timet_with_zone(tm2,0,azone),
		    icalparameter_new_tzid("America/New_York"),0),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("America/New_York", span.start, 973396800);

    icalcomponent_free(c);

    /** test 4
     *	We specify times in two different timezones, the returned span
     *	is in UTC
     */
    azone = icaltimezone_get_builtin_timezone("America/New_York");
    bzone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_vanew_dtstart(
		    icaltime_from_timet_with_zone(tm1,0,azone),
		    icalparameter_new_tzid("America/New_York"),0),
		icalproperty_vanew_dtend(
		    icaltime_from_timet_with_zone(tm2,0,bzone),
		    icalparameter_new_tzid("America/Los_Angeles"),0),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("America/New_York", span.start, 973396800);
    
    icalcomponent_free(c);

    /** test 5
     *	We specify start time in a timezone and a duration, the returned span
     *	is in UTC
     */
    azone = icaltimezone_get_builtin_timezone("America/Los_Angeles");
    memset(&dur,0,sizeof(dur));
    dur.minutes = 30;
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_vanew_dtstart(
		    icaltime_from_timet_with_zone(tm1,0,azone),
		    icalparameter_new_tzid("America/Los_Angeles"),0),
	    icalproperty_new_duration(dur),

	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("America/Los_Angeles w/ duration", span.end, 973409400);

    icalcomponent_free(c);

    icalerror_errors_are_fatal = 0;
    /** test 6
     *	We specify only start time, should return a null span with no error
     */
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstart(icaltime_from_timet(tm1,0)),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("null span", span.start, 0);
    icalcomponent_free(c);

    /** test 7
     *	We specify start and end date
     */
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
		icalproperty_new_dtend(icaltime_from_timet(tm1,1)),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("UTC", span.start, 973296000);
    icalcomponent_free(c);

    /** test 8
     *	We specify start and end date
     */
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
		icalproperty_new_dtend(icaltime_from_timet(tm2,1)),
	    0
	    );

    span = icalcomponent_get_span(c);
    int_is("UTC #2", span.start, 973296000);
    if (VERBOSE) print_span(tnum++,span);

    icalcomponent_free(c);

    /** test 9
     *	We specify start date
     */
    c = icalcomponent_vanew(
	    ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstart(icaltime_from_timet(tm1,1)),
	    0
	    );

    span = icalcomponent_get_span(c);
    if (VERBOSE) print_span(tnum++,span);
    int_is("start date only", span.end, 973382399);

    icalcomponent_free(c);

    /* assert(icalerrno == ICAL_MALFORMEDDATA_ERROR); */
    icalerror_errors_are_fatal = 1;
}
void create_new_component_with_va_args()
{

    icalcomponent* calendar;
    struct icaltimetype atime = icaltime_from_timet( time(0),0);
    struct icaldatetimeperiodtype rtime;
    
    rtime.period.start = icaltime_from_timet( time(0),0);
    rtime.period.end = icaltime_from_timet( time(0),0);
    rtime.period.end.hour++;
    rtime.time = icaltime_null_time();

    calendar = 
	icalcomponent_vanew(
	    ICAL_VCALENDAR_COMPONENT,
	    icalproperty_new_version("2.0"),
	    icalproperty_new_prodid("-//RDU Software//NONSGML HandCal//EN"),
	    icalcomponent_vanew(
		ICAL_VTIMEZONE_COMPONENT,
		icalproperty_new_tzid("America/New_York"),
		icalcomponent_vanew(
		    ICAL_XDAYLIGHT_COMPONENT,
		    icalproperty_new_dtstart(atime),
		    icalproperty_new_rdate(rtime),
		    icalproperty_new_tzoffsetfrom(-4.0),
		    icalproperty_new_tzoffsetto(-5.0),
		    icalproperty_new_tzname("EST"),
		    NULL
		    ),
		icalcomponent_vanew(
		    ICAL_XSTANDARD_COMPONENT,
		    icalproperty_new_dtstart(atime),
		    icalproperty_new_rdate(rtime),
		    icalproperty_new_tzoffsetfrom(-5.0),
		    icalproperty_new_tzoffsetto(-4.0),
		    icalproperty_new_tzname("EST"),
		    NULL
		    ),
		NULL
		),
	    icalcomponent_vanew(
		ICAL_VEVENT_COMPONENT,
		icalproperty_new_dtstamp(atime),
		icalproperty_new_uid("guid-1.host1.com"),
		icalproperty_vanew_organizer(
		    "*****@*****.**",
		    icalparameter_new_role(ICAL_ROLE_CHAIR),
		    NULL
		    ),
		icalproperty_vanew_attendee(
		    "*****@*****.**",
		    icalparameter_new_role(ICAL_ROLE_REQPARTICIPANT),
		    icalparameter_new_rsvp(ICAL_RSVP_TRUE),
		    icalparameter_new_cutype(ICAL_CUTYPE_GROUP),
		    NULL
		    ),
		icalproperty_new_description("Project XYZ Review Meeting"),
		icalproperty_new_categories("MEETING"),
		icalproperty_new_class(ICAL_CLASS_PUBLIC),
		icalproperty_new_created(atime),
		icalproperty_new_summary("XYZ Project Review"),
		icalproperty_vanew_dtstart(
		    atime,
		    icalparameter_new_tzid("America/New_York"),
		    NULL
		    ),
		icalproperty_vanew_dtend(
		    atime,
		    icalparameter_new_tzid("America/New_York"),
		    NULL
		    ),
		icalproperty_new_location("1CP Conference Room 4350"),
		NULL
		),
	    NULL
	    );

    ok("creating a complex vcalendar", (calendar != NULL));
    if (VERBOSE && calendar)
      printf("%s\n",icalcomponent_as_ical_string(calendar));

    icalcomponent_free(calendar);

}
void ical_property_EXDATE(struct exchange2ical *exchange2ical)
{
	uint32_t	i;
	uint32_t	j;
	uint8_t		modified;
	struct icaltimetype	icaltime;
	struct icaltimetype	dttime;

	icalproperty	*prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;

	/* Sanity check */
	if (exchange2ical->Recurring && (*exchange2ical->Recurring == 0x0)) return;
	if (!pat) return;
	if (!pat->DeletedInstanceCount) return;

	for (i = 0; i < pat->DeletedInstanceCount; i++) {
		modified=0;
		if(pat->ModifiedInstanceDates && pat->ModifiedInstanceCount){
			for(j=0; j < pat->ModifiedInstanceCount; j++){
				if(pat->ModifiedInstanceDates[j]==pat->DeletedInstanceDates[i]){
					modified=1;
					break;
				}
			}
		}
		/* If this is an all-day appointment */
		if (!modified && exchange2ical->apptSubType && (*exchange2ical->apptSubType == 0x1)) {
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
			icaltime= get_icaldate_from_tm(&tm);
			prop = icalproperty_new_exdate(icaltime);
			icalcomponent_add_property(exchange2ical->vevent, prop);
		} else if (!modified){
			/* number of minutes between midnight of the specified
			* day and midnight, January 1, 1601 */
			struct tm	tm;
			tm = get_tm_from_minutes_UTC(pat->DeletedInstanceDates[i]);
			icaltime= get_icaltimetype_from_tm(&tm);

			if (exchange2ical->TimeZoneDesc) {
				/*Get time from dtstart*/
				if (exchange2ical->apptEndWhole){
					dttime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
					icaltime.hour   = dttime.hour;
					icaltime.minute = dttime.minute;
				}

				prop = icalproperty_new_exdate(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
				icalparameter *tzid = icalparameter_new_tzid(exchange2ical->TimeZoneDesc);
				icalproperty_add_parameter(prop, tzid);
			} else {
				/*Get time from dtstart*/
				icaltime.is_utc = 1;
				if (exchange2ical->apptEndWhole){
					dttime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
					icaltime.hour   = dttime.hour;
					icaltime.minute = dttime.minute;
				}
				prop = icalproperty_new_exdate(icaltime);
				icalcomponent_add_property(exchange2ical->vevent, prop);
			}
		}		
		
	}
}