コード例 #1
0
void ical_property_RRULE_Yearly(struct exchange2ical *exchange2ical)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
	uint32_t day = pat->PatternTypeSpecific.Day;
	struct icaltimetype icaltime;

	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_YEARLY_RECURRENCE;
	recurrence.interval = (pat->Period / 12);

	if (day == 0x0000001F) {
		recurrence.by_month_day[0] = -1;
	} else {
		recurrence.by_month_day[0] = day;
	}
	recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;

	icaltime = get_icaltime_from_FILETIME_UTC(exchange2ical->apptStartWhole);
	recurrence.by_month[0] = icaltime.month;
	recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;


	
	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
		recurrence.count = pat->OccurrenceCount;
	} 
	
	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
コード例 #2
0
void ical_property_RRULE_daylight_standard(icalcomponent* component , struct SYSTEMTIME st)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	
	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_YEARLY_RECURRENCE;

	if(st.wYear ==0x0000){
		recurrence.by_month[0]=st.wMonth;
		/* Microsoft day of week = libIcal day of week +1; */
		/* Day encode = day + occurrence*8 */
		if (st.wDay==5){
			/* Last occurrence of day in the month*/
			recurrence.by_day[0] = -1 * (st.wDayOfWeek + 9);
		}else{
			/* st.wDay occurrence of day in the month */
			recurrence.by_day[0] = (st.wDayOfWeek + 1 + st.wDay*8);
		}
		
	}else{
		recurrence.by_month_day[0]=st.wDay;
		recurrence.by_month[0]=st.wMonth;
	}

	
	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(component, prop);
}
コード例 #3
0
void ical_property_RRULE_Monthly(struct exchange2ical *exchange2ical)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
	uint32_t day = pat->PatternTypeSpecific.Day;

	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_MONTHLY_RECURRENCE;
	recurrence.interval = pat->Period;

	if (day == 0x0000001F) {
		recurrence.by_month_day[0] = -1;
	} else {
		recurrence.by_month_day[0] = day;
	}
	recurrence.by_month_day[1] = ICAL_RECURRENCE_ARRAY_MAX;

	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
		recurrence.count = pat->OccurrenceCount;
	}

	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
コード例 #4
0
void ical_property_RRULE_Daily(struct exchange2ical *exchange2ical)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;


	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_DAILY_RECURRENCE;
	recurrence.interval = (pat->Period / 1440);

	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
		recurrence.count = pat->OccurrenceCount;
	}
	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
コード例 #5
0
ファイル: vcal.c プロジェクト: ihipop/I-GNOKII
/*
	ICALENDAR Reading functions
 */
GNOKII_API char *gn_calnote2icalstr(gn_calnote *calnote)
{
	ical_string str;

#ifdef HAVE_LIBICAL
	icalcomponent *pIcal = NULL, *vevent;
	struct icaltimetype stime = {0}, etime = {0};
	char compuid[64];

	memset(&str, 0, sizeof (str));

	/* In at least some Nokia phones it is possible to skip the year of
	   birth, in this case year == 0xffff, so we set it to the arbitrary
	   value of 1800 */

	stime.year = (calnote->time.year == 0xffff ? 1800 : calnote->time.year);
	stime.month = calnote->time.month;
	stime.day = calnote->time.day;
	stime.hour = calnote->time.hour;
	stime.minute = calnote->time.minute;
	stime.second = calnote->time.second;

	stime.is_daylight = 1;

	snprintf(compuid, sizeof(compuid), "guid.gnokii.org_%d_%d", calnote->location, rand());

	vevent = icalcomponent_vanew(ICAL_VEVENT_COMPONENT,
				     icalproperty_new_dtstart(stime),
				     icalproperty_new_uid(compuid),
				     icalproperty_new_categories("GNOKII"),
				     0);
	if (!vevent) {
		dprintf("ERROR in icalcomponent_vanew() creating VEVENT\n");
		return NULL;
	}

	if (calnote->end_time.year) {
		etime.year = (calnote->end_time.year == 0xffff ? 1800 : calnote->end_time.year);
		etime.month = calnote->end_time.month;
		etime.day = calnote->end_time.day;
		etime.hour = calnote->end_time.hour;
		etime.minute = calnote->end_time.minute;
		etime.second = calnote->end_time.second;
		etime.is_daylight = 1;

		icalcomponent_add_property(vevent, icalproperty_new_dtend(etime));
	}

	/* TODO: should the strings be configurable? */
	switch(calnote->type) {
	case GN_CALNOTE_MEMO:
		icalcomponent_add_property(vevent, icalproperty_new_categories("MISCELLANEOUS"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	case GN_CALNOTE_REMINDER:
		icalcomponent_add_property(vevent, icalproperty_new_categories("REMINDER"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	case GN_CALNOTE_CALL:
		icalcomponent_add_property(vevent, icalproperty_new_categories("PHONE CALL"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->phone_number));
		icalcomponent_add_property(vevent, icalproperty_new_description(calnote->text));
		break;
	case GN_CALNOTE_MEETING:
		icalcomponent_add_property(vevent, icalproperty_new_categories("MEETING"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		if (calnote->mlocation[0])
			icalcomponent_add_property(vevent, icalproperty_new_location(calnote->mlocation));
		break;
	case GN_CALNOTE_BIRTHDAY:
		icalcomponent_add_property(vevent, icalproperty_new_categories("ANNIVERSARY"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		stime.is_date = 1;
		calnote->recurrence = GN_CALNOTE_YEARLY;
		break;
	default:
		icalcomponent_add_property(vevent, icalproperty_new_categories("UNKNOWN"));
		icalcomponent_add_property(vevent, icalproperty_new_summary(calnote->text));
		break;
	}

	if (calnote->recurrence) {
		char rrule[64];
		char *freq;
		int interval = 1;

		switch (calnote->recurrence) {
		case GN_CALNOTE_NEVER:
			goto norecurrence;
		case GN_CALNOTE_DAILY:
			freq = "DAILY";
			break;
		case GN_CALNOTE_WEEKLY:
			freq = "WEEKLY";
			break;
		case GN_CALNOTE_2WEEKLY:
			freq = "WEEKLY";
			interval = 2;
			break;
		case GN_CALNOTE_MONTHLY:
			freq = "MONTHLY";
			break;
		case GN_CALNOTE_YEARLY:
			freq = "YEARLY";
			break;
		default:
			freq = "HOURLY";
			interval = calnote->recurrence;
			break;
		}
		if (calnote->type == GN_CALNOTE_BIRTHDAY)
			snprintf(rrule, sizeof(rrule), "FREQ=YEARLY;INTERVAL=1;BYMONTH=%d", stime.month);
		else if (calnote->occurrences == 0)
			snprintf(rrule, sizeof(rrule), "FREQ=%s;INTERVAL=%d", freq, interval);
		else
			snprintf(rrule, sizeof(rrule), "FREQ=%s;COUNT=%d;INTERVAL=%d", freq, calnote->occurrences, interval);
		icalcomponent_add_property(vevent, icalproperty_new_rrule(icalrecurrencetype_from_string(rrule)));
	}
norecurrence:

	if (calnote->alarm.enabled) {
		icalcomponent *valarm;
		struct icaltriggertype trig;

		trig.time.year = (calnote->alarm.timestamp.year == 0xffff ? 1800 : calnote->alarm.timestamp.year);
		trig.time.month = calnote->alarm.timestamp.month;
		trig.time.day = calnote->alarm.timestamp.day;
		trig.time.hour = calnote->alarm.timestamp.hour;
		trig.time.minute = calnote->alarm.timestamp.minute;
		trig.time.second = calnote->alarm.timestamp.second;
		trig.time.is_daylight = 1;

		valarm = icalcomponent_new_valarm();

		icalcomponent_add_property(valarm, icalproperty_new_trigger(trig));
		/* FIXME: with ICAL_ACTION_DISPLAY a DESCRIPTION property is mandatory */
		icalcomponent_add_property(valarm, icalproperty_new_action(calnote->alarm.tone ? ICAL_ACTION_AUDIO : ICAL_ACTION_DISPLAY));

		icalcomponent_add_component(vevent, valarm);
	}

	pIcal = icalcomponent_vanew(ICAL_VCALENDAR_COMPONENT,
				    icalproperty_new_version("2.0"),
				    icalproperty_new_prodid(get_prodid()),
				    vevent,
				    0);

	if (pIcal) {
		char *icalstrbuf = NULL;
		const char *icalstr = icalcomponent_as_ical_string(pIcal);

		/* conversion to UTF-8 */
		if (string_base64(icalstr)) {
			int icalstrlen = strlen(icalstr);
			icalstrbuf = malloc(icalstrlen * 2 + 1);
			utf8_encode(icalstrbuf, icalstrlen * 2, icalstr, icalstrlen);

			icalstr = icalstrbuf;
		}
		ical_append_printf(&str, "%s\n", icalstr);
		dprintf("%s\n", icalstr);
		if (icalstrbuf)
			free(icalstrbuf);

		icalcomponent_free(pIcal);
		pIcal = NULL;
	} else {
		dprintf("ERROR in icalcomponent_vanew() creating VCALENDAR\n");
	}
	return str.str;
#else
	memset(&str, 0, sizeof (str));

	ical_append_printf(&str, "BEGIN:VCALENDAR\r\n");
	ical_append_printf(&str, "VERSION:1.0\r\n");
	ical_append_printf(&str, "BEGIN:VEVENT\r\n");
	ical_append_printf(&str, "CATEGORIES:");
	switch (calnote->type) {
	case GN_CALNOTE_MEMO:
		ical_append_printf(&str, "MISCELLANEOUS\r\n");
		break;
	case GN_CALNOTE_REMINDER:
		ical_append_printf(&str, "REMINDER\r\n");
		break;
	case GN_CALNOTE_CALL: 
		ical_append_printf(&str, "PHONE CALL\r\n");
		ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->phone_number);
		ical_append_printf(&str, "DESCRIPTION:%s\r\n", calnote->text);
		break; 
	case GN_CALNOTE_MEETING: 
		ical_append_printf(&str, "MEETING\r\n"); 
		if (calnote->mlocation[0])
			ical_append_printf(&str, "LOCATION:%s\r\n", calnote->mlocation);
		break; 
	case GN_CALNOTE_BIRTHDAY: 
		ical_append_printf(&str, "SPECIAL OCCASION\r\n"); 
		break; 
	default: 
		ical_append_printf(&str, "UNKNOWN\r\n"); 
		break; 
	} 
	if (calnote->type != GN_CALNOTE_CALL)
		ical_append_printf(&str, "SUMMARY:%s\r\n", calnote->text);
	ical_append_printf(&str, "DTSTART:%04d%02d%02dT%02d%02d%02d\r\n", calnote->time.year,
		calnote->time.month, calnote->time.day, calnote->time.hour, 
		calnote->time.minute, calnote->time.second); 
	if (calnote->end_time.year) {
		ical_append_printf(&str, "DTEND:%04d%02d%02dT%02d%02d%02d\r\n", calnote->end_time.year, 
			calnote->end_time.month, calnote->end_time.day, calnote->end_time.hour, 
			calnote->end_time.minute, calnote->end_time.second); 
	}
	if (calnote->alarm.enabled) {
		ical_append_printf(&str, "%sALARM:%04d%02d%02dT%02d%02d%02d\r\n",
		(calnote->alarm.tone ? "A" : "D"),
		calnote->alarm.timestamp.year, 
		calnote->alarm.timestamp.month, calnote->alarm.timestamp.day, calnote->alarm.timestamp.hour, 
		calnote->alarm.timestamp.minute, calnote->alarm.timestamp.second); 
	} 
	switch (calnote->recurrence) { 
	case GN_CALNOTE_NEVER: 
		break; 
	case GN_CALNOTE_DAILY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=DAILY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=DAILY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_WEEKLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_2WEEKLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=WEEKLY;INTERVAL=2;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_MONTHLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=MONTHLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=MONTHLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	case GN_CALNOTE_YEARLY: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=YEARLY\r\n") :
			ical_append_printf(&str, "RRULE:FREQ=YEARLY;COUNT=%d\r\n", calnote->occurrences);
		break; 
	default: 
		calnote->occurrences ?
			ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d\r\n", calnote->recurrence) :
			ical_append_printf(&str, "RRULE:FREQ=HOURLY;INTERVAL=%d;COUNT=%d\r\n", calnote->recurrence, calnote->occurrences);
		break; 
	} 
	ical_append_printf(&str, "END:VEVENT\r\n"); 
	ical_append_printf(&str, "END:VCALENDAR\r\n");
	return str.str;
#endif /* HAVE_LIBICAL */
}
コード例 #6
0
icalcomponent *icaltzutil_fetch_timezone(const char *location)
{
    tzinfo type_cnts;
    size_t i, num_trans, num_chars, num_leaps, num_isstd, num_isgmt;
    size_t num_types = 0;
    size_t size;
    time_t trans;
    int dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx;
    icalcomponent *std_comp = NULL;

    const char *zonedir;
    FILE *f = NULL;
    char *full_path = NULL;
    time_t *transitions = NULL;
    char *r_trans = NULL, *temp;
    int *trans_idx = NULL;
    ttinfo *types = NULL;
    char *znames = NULL;
    leap *leaps = NULL;
    char *tzid = NULL;

    time_t start, end;
    int idx, prev_idx;
    icalcomponent *tz_comp = NULL, *comp = NULL, *dst_comp;
    icalproperty *icalprop;
    icaltimetype dtstart, icaltime;
    struct icalrecurrencetype ical_recur;

    if (icaltimezone_get_builtin_tzdata()) {
        goto error;
    }

    zonedir = icaltzutil_get_zone_directory();
    if (!zonedir) {
        icalerror_set_errno(ICAL_FILE_ERROR);
        goto error;
    }

    size = strlen(zonedir) + strlen(location) + 2;
    full_path = (char *)malloc(size);
    if (full_path == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    snprintf(full_path, size, "%s/%s", zonedir, location);
    if ((f = fopen(full_path, "rb")) == 0) {
        icalerror_set_errno(ICAL_FILE_ERROR);
        goto error;
    }

    if (fseek(f, 20, SEEK_SET) != 0) {
        icalerror_set_errno(ICAL_FILE_ERROR);
        goto error;
    }

    EFREAD(&type_cnts, 24, 1, f);

    num_isgmt = (size_t)decode(type_cnts.ttisgmtcnt);
    num_leaps = (size_t)decode(type_cnts.leapcnt);
    num_chars = (size_t)decode(type_cnts.charcnt);
    num_trans = (size_t)decode(type_cnts.timecnt);
    num_isstd = (size_t)decode(type_cnts.ttisstdcnt);
    num_types = (size_t)decode(type_cnts.typecnt);

    transitions = calloc(num_trans, sizeof(time_t));
    if (transitions == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    r_trans = calloc(num_trans, 4);
    if (r_trans == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }

    EFREAD(r_trans, 4, num_trans, f);
    temp = r_trans;
    if (num_trans) {
        trans_idx = calloc(num_trans, sizeof(int));
        if (trans_idx == NULL) {
            icalerror_set_errno(ICAL_NEWFAILED_ERROR);
            goto error;
        }
        for (i = 0; i < num_trans; i++) {
            trans_idx[i] = fgetc(f);
            transitions[i] = (time_t) decode(r_trans);
            r_trans += 4;
        }
    }
    r_trans = temp;

    types = calloc(num_types, sizeof(ttinfo));
    if (types == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    for (i = 0; i < num_types; i++) {
        unsigned char a[4];
        int c;

        EFREAD(a, 4, 1, f);
        c = fgetc(f);
        types[i].isdst = (unsigned char)c;
        if ((c = fgetc(f)) < 0) {
            break;
        }
        types[i].abbr = (unsigned int)c;
        types[i].gmtoff = decode(a);
    }

    znames = (char *)malloc(num_chars);
    if (znames == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    EFREAD(znames, num_chars, 1, f);

    /* We got all the information which we need */

    leaps = calloc(num_leaps, sizeof(leap));
    if (leaps == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    for (i = 0; i < num_leaps; i++) {
        char c[4];

        EFREAD(c, 4, 1, f);
        leaps[i].transition = (time_t)decode(c);

        EFREAD(c, 4, 1, f);
        leaps[i].change = decode(c);
    }

    for (i = 0; i < num_isstd; ++i) {
        int c = getc(f);
        types[i].isstd = c != 0;
    }

    while (i < num_types) {
        types[i++].isstd = 0;
    }

    for (i = 0; i < num_isgmt; ++i) {
        int c = getc(f);

        types[i].isgmt = c != 0;
    }

    while (i < num_types) {
        types[i++].isgmt = 0;
    }

    /* Read all the contents now */

    for (i = 0; i < num_types; i++) {
        /* coverity[tainted_data] */
        types[i].zname = zname_from_stridx(znames, types[i].abbr);
    }

    if (!_s_use_exact_timezones) {
        if (num_trans != 0) {
            find_transidx(transitions, types, trans_idx, (long int)num_trans, &stdidx, &dstidx);
        } else {
            stdidx = 0;
        }
    }

    tz_comp = icalcomponent_new(ICAL_VTIMEZONE_COMPONENT);

    /* Add tzid property */
    size = strlen(icaltimezone_tzid_prefix()) + strlen(location) + 1;
    tzid = (char *)malloc(size);
    if (tzid == NULL) {
        icalerror_set_errno(ICAL_NEWFAILED_ERROR);
        goto error;
    }
    snprintf(tzid, size, "%s%s", icaltimezone_tzid_prefix(), location);
    icalprop = icalproperty_new_tzid(tzid);
    icalcomponent_add_property(tz_comp, icalprop);

    icalprop = icalproperty_new_x(location);
    icalproperty_set_x_name(icalprop, "X-LIC-LOCATION");
    icalcomponent_add_property(tz_comp, icalprop);

    if (!_s_use_exact_timezones) {
        if (stdidx != -1) {
            if (num_trans != 0) {
                zidx = trans_idx[stdidx];
            } else {
                zidx = 0;
            }

            std_comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
            icalprop = icalproperty_new_tzname(types[zidx].zname);
            icalcomponent_add_property(std_comp, icalprop);

            if (dstidx != -1) {
                zp_idx = trans_idx[stdidx-1];
            } else {
                zp_idx = zidx;
            }
            /* DTSTART localtime uses TZOFFSETFROM UTC offset */
            if (num_trans != 0) {
                trans = transitions[stdidx] + types[zp_idx].gmtoff;
            } else {
                trans = (time_t)types[zp_idx].gmtoff;
            }
            icaltime = icaltime_from_timet_with_zone(trans, 0, NULL);
            dtstart = icaltime;
            dtstart.year = 1970;
            dtstart.minute = dtstart.second = 0;
            icalprop = icalproperty_new_dtstart(dtstart);
            icalcomponent_add_property(std_comp, icalprop);

            /* If DST changes are present use RRULE */
            if (dstidx != -1) {
                icalrecurrencetype_clear(&ical_recur);
                ical_recur.freq = ICAL_YEARLY_RECURRENCE;
                ical_recur.by_month[0] = icaltime.month;
                pos = calculate_pos(icaltime);
                pos < 0 ? (sign = -1): (sign = 1);
                ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime));
                icalprop = icalproperty_new_rrule(ical_recur);
                icalcomponent_add_property(std_comp, icalprop);

                adjust_dtstart_day_to_rrule(std_comp, ical_recur);
            }
            icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff);
            icalcomponent_add_property(std_comp, icalprop);
            icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff);
            icalcomponent_add_property(std_comp, icalprop);
            icalcomponent_add_component(tz_comp, std_comp);
        } else {
            icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR);
        }

        if (dstidx != -1) {
            zidx = trans_idx[dstidx];
            zp_idx = trans_idx[dstidx-1];
            dst_comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
            icalprop = icalproperty_new_tzname(types[zidx].zname);
            icalcomponent_add_property(dst_comp, icalprop);

            /* DTSTART localtime uses TZOFFSETFROM UTC offset */
            trans = transitions[dstidx] + types[zp_idx].gmtoff;

            icaltime = icaltime_from_timet_with_zone(trans, 0, NULL);
            dtstart = icaltime;
            dtstart.year = 1970;
            dtstart.minute = dtstart.second = 0;
            icalprop = icalproperty_new_dtstart(dtstart);
            icalcomponent_add_property(dst_comp, icalprop);

            icalrecurrencetype_clear(&ical_recur);
            ical_recur.freq = ICAL_YEARLY_RECURRENCE;
            ical_recur.by_month[0] = icaltime.month;
            pos = calculate_pos(icaltime);
            pos < 0 ? (sign = -1): (sign = 1);
            ical_recur.by_day[0] = sign * ((abs(pos) * 8) + icaltime_day_of_week(icaltime));
            icalprop = icalproperty_new_rrule(ical_recur);
            icalcomponent_add_property(dst_comp, icalprop);

            adjust_dtstart_day_to_rrule(dst_comp, ical_recur);

            icalprop = icalproperty_new_tzoffsetfrom(types[zp_idx].gmtoff);
            icalcomponent_add_property(dst_comp, icalprop);

            icalprop = icalproperty_new_tzoffsetto(types[zidx].gmtoff);
            icalcomponent_add_property(dst_comp, icalprop);

            icalcomponent_add_component(tz_comp, dst_comp);
        }
    } else { /*exact vtimezones*/
        prev_idx = 0;
        if (num_trans == 0) {
            prev_idx = idx = 0;
        } else {
            idx = trans_idx[0];
        }
        start = 0;
        for (i = 1; i < num_trans; i++, start = end) {
            prev_idx = idx;
            idx = trans_idx[i];
            end = transitions[i] + types[prev_idx].gmtoff;
            /* don't bother starting until the epoch */
            if (0 > end)
                continue;

            if (types[prev_idx].isdst) {
                comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
            } else {
                comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
            }
            icalprop = icalproperty_new_tzname(types[prev_idx].zname);
            icalcomponent_add_property(comp, icalprop);
            dtstart = icaltime_from_timet_with_zone(start, 0, NULL);
            icalprop = icalproperty_new_dtstart(dtstart);
            icalcomponent_add_property(comp, icalprop);
            icalprop = icalproperty_new_tzoffsetfrom(types[idx].gmtoff);
            icalcomponent_add_property(comp, icalprop);
            icalprop = icalproperty_new_tzoffsetto(types[prev_idx].gmtoff);
            icalcomponent_add_property(comp, icalprop);
            icalcomponent_add_component(tz_comp, comp);
        }
        /* finally, add a last zone with no end date */
        if (types[idx].isdst) {
            comp = icalcomponent_new(ICAL_XDAYLIGHT_COMPONENT);
        } else {
            comp = icalcomponent_new(ICAL_XSTANDARD_COMPONENT);
        }
        icalprop = icalproperty_new_tzname(types[idx].zname);
        icalcomponent_add_property(comp, icalprop);
        dtstart = icaltime_from_timet_with_zone(start, 0, NULL);
        icalprop = icalproperty_new_dtstart(dtstart);
        icalcomponent_add_property(comp, icalprop);
        icalprop = icalproperty_new_tzoffsetfrom(types[prev_idx].gmtoff);
        icalcomponent_add_property(comp, icalprop);
        icalprop = icalproperty_new_tzoffsetto(types[idx].gmtoff);
        icalcomponent_add_property(comp, icalprop);
        icalcomponent_add_component(tz_comp, comp);
    }

  error:
    if (f)
        fclose(f);

    if (full_path)
        free(full_path);

    if (transitions)
        free(transitions);

    if (r_trans)
        free(r_trans);

    if (trans_idx)
        free(trans_idx);

    if (types) {
        for (i = 0; i < num_types; i++) {
            if (types[i].zname) {
                free(types[i].zname);
            }
        }
        free(types);
    }

    if (znames)
        free(znames);

    if (leaps)
        free(leaps);

    if (tzid)
        free(tzid);

    return tz_comp;
}
コード例 #7
0
void ical_property_RRULE_NthYearly(struct exchange2ical *exchange2ical)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
	uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.MonthRecurrencePattern.WeekRecurrencePattern;
	short idx = 0;
	enum RecurrenceN setpos = pat->PatternTypeSpecific.MonthRecurrencePattern.N;

	struct icaltimetype icaltime;

	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_YEARLY_RECURRENCE;
	recurrence.interval = (pat->Period / 12);

	if (rdfDaysBitmask & Su) {
		recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & M) {
		recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Tu) {
		recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & W) {
		recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Th) {
		recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & F) {
		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Sa) {
		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
		++idx;
	}
	recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;

	if (setpos == RecurrenceN_First) {
		recurrence.by_set_pos[0] = 1;
		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
	} else if (setpos == RecurrenceN_Second) {
		recurrence.by_set_pos[0] = 2;
		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
	} else if (setpos == RecurrenceN_Third) {
		recurrence.by_set_pos[0] = 3;
		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
	} else if (setpos == RecurrenceN_Fourth) {
		recurrence.by_set_pos[0] = 4;
		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
	} else if (setpos == RecurrenceN_Last) {
		recurrence.by_set_pos[0] = -1;
		recurrence.by_set_pos[1] = ICAL_RECURRENCE_ARRAY_MAX;
	}

	icaltime = get_icaltime_from_FILETIME(exchange2ical->apptStartWhole);
	recurrence.by_month[0] = icaltime.month;
	recurrence.by_month[1] = ICAL_RECURRENCE_ARRAY_MAX;
	
	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
		recurrence.count = pat->OccurrenceCount;
	}

	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
コード例 #8
0
void ical_property_RRULE_Weekly(struct exchange2ical *exchange2ical)
{
	struct icalrecurrencetype recurrence;
	icalproperty *prop;
	struct RecurrencePattern *pat = exchange2ical->RecurrencePattern;
	uint32_t rdfDaysBitmask = pat->PatternTypeSpecific.WeekRecurrencePattern;
	short idx = 0;

	icalrecurrencetype_clear(&recurrence);
	recurrence.freq = ICAL_WEEKLY_RECURRENCE;
	recurrence.interval = pat->Period;
	
	if(pat->Period > 1){
		switch(pat->FirstDOW){
			case FirstDOW_Sunday:
				recurrence.week_start=ICAL_SUNDAY_WEEKDAY;
				break;
			case FirstDOW_Monday:
				recurrence.week_start=ICAL_MONDAY_WEEKDAY;
				break;
			case FirstDOW_Tuesday:
				recurrence.week_start=ICAL_TUESDAY_WEEKDAY;
				break;
			case FirstDOW_Wednesday:
				recurrence.week_start=ICAL_WEDNESDAY_WEEKDAY;
				break;
			case FirstDOW_Thursday:
				recurrence.week_start=ICAL_THURSDAY_WEEKDAY;
				break;
			case FirstDOW_Friday:
				recurrence.week_start=ICAL_FRIDAY_WEEKDAY;
				break;
			case FirstDOW_Saturday:
				recurrence.week_start=ICAL_SATURDAY_WEEKDAY;
				break;
		}
	}
	
	if (rdfDaysBitmask & Su) {
		recurrence.by_day[idx] = ICAL_SUNDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & M) {
		recurrence.by_day[idx] = ICAL_MONDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Tu) {
		recurrence.by_day[idx] = ICAL_TUESDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & W) {
		recurrence.by_day[idx] = ICAL_WEDNESDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Th) {
		recurrence.by_day[idx] = ICAL_THURSDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & F) {
		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
		++idx;
	}
	if (rdfDaysBitmask & Sa) {
		recurrence.by_day[idx] = ICAL_FRIDAY_WEEKDAY;
		++idx;
	}
	recurrence.by_day[idx] = ICAL_RECURRENCE_ARRAY_MAX;

	if (pat->EndType == END_AFTER_N_OCCURRENCES || pat->EndType == END_AFTER_DATE) {
		recurrence.count = pat->OccurrenceCount;
	}

	prop = icalproperty_new_rrule(recurrence);
	icalcomponent_add_property(exchange2ical->vevent, prop);
}
コード例 #9
0
icalcomponent*
icaltzutil_fetch_timezone (const char *location)
{
	int ret = 0;
	FILE *f;
	tzinfo type_cnts;
	unsigned int num_trans, num_types, num_chars, num_leaps, num_isstd, num_isgmt;
	time_t *transitions = NULL;
	time_t trans;
	int *trans_idx = NULL, dstidx = -1, stdidx = -1, pos, sign, zidx, zp_idx, i;
	ttinfo *types = NULL;
	char *znames = NULL, *full_path, *tzid, *r_trans, *temp;
	leap *leaps = NULL;
	icalcomponent *tz_comp = NULL, *dst_comp = NULL, *std_comp = NULL;
	icalproperty *icalprop;
	icaltimetype dtstart, icaltime;
	struct icalrecurrencetype ical_recur;
	       
	if (!zdir) 
		set_zone_directory ();
	
	full_path = (char *) malloc (strlen (zdir) + strlen (location) + 2);
	sprintf (full_path,"%s/%s",zdir, location);

	if ((f = fopen (full_path, "rb")) == 0) {
		icalerror_set_errno (ICAL_FILE_ERROR);
		free (full_path);
		return NULL;
	}

	if ((ret = fseek (f, 20, SEEK_SET)) != 0) {
		icalerror_set_errno (ICAL_FILE_ERROR);
		goto error;	
	}

	EFREAD(&type_cnts, 24, 1, f);

	num_isgmt = decode (type_cnts.ttisgmtcnt);
	num_leaps = decode (type_cnts.leapcnt);
	num_chars = decode (type_cnts.charcnt);
	num_trans = decode (type_cnts.timecnt);
	num_isstd = decode (type_cnts.ttisstdcnt);
	num_types = decode (type_cnts.typecnt);

	transitions = calloc (num_trans, sizeof (time_t));
	r_trans = calloc (num_trans, 4);
	EFREAD(r_trans, 4, num_trans, f);
	temp = r_trans;	

	if (num_trans) {
		trans_idx = calloc (num_trans, sizeof (int));
		for (i = 0; i < num_trans; i++) {
			trans_idx [i] = fgetc (f);
			transitions [i] = decode (r_trans);
			r_trans += 4;
		}
	}
	
	free (temp);

	types = calloc (num_types, sizeof (ttinfo));
	for (i = 0; i < num_types; i++) {
		unsigned char a [4];
		int c;

		EFREAD(a, 4, 1, f);
		c = fgetc (f);
		types [i].isdst = c;
		if((c = fgetc (f)) < 0) {
		   c = 0;
		   break;
		}
		types [i].abbr = c;
		types [i].gmtoff = decode (a);
	}

	znames = (char *) malloc (num_chars);
	EFREAD(znames, num_chars, 1, f);

	/* We got all the information which we need */

	leaps = calloc (num_leaps, sizeof (leap));
	for (i = 0; i < num_leaps; i++) {
		char c [4];

		EFREAD (c, 4, 1, f);
		leaps [i].transition = decode (c);

		EFREAD (c, 4, 1, f);
		leaps [i].change = decode (c);
	}

	for (i = 0; i < num_isstd; ++i) {
		int c = getc (f);
		types [i].isstd = c != 0;
	}

	while (i < num_types)
		types [i++].isstd = 0;

	for (i = 0; i <  num_isgmt; ++i) {
		int c = getc (f);
		types [i].isgmt = c != 0;
	}

	while (i < num_types)
		types [i++].isgmt = 0;

	/* Read all the contents now */

	for (i = 0; i < num_types; i++) 
		types [i].zname = zname_from_stridx (znames, types [i].abbr);

	if (num_trans != 0)
		find_transidx (transitions, types, trans_idx, num_trans, &stdidx, &dstidx);
	else
		stdidx = 0;

	tz_comp = icalcomponent_new (ICAL_VTIMEZONE_COMPONENT);

	/* Add tzid property */
	tzid = (char *) malloc (strlen (ical_tzid_prefix) + strlen (location) + 8);
	sprintf (tzid, "%sTzfile/%s", ical_tzid_prefix, location);
	icalprop = icalproperty_new_tzid (tzid);
	icalcomponent_add_property (tz_comp, icalprop);
	free (tzid);

	icalprop = icalproperty_new_x (location);
	icalproperty_set_x_name (icalprop, "X-LIC-LOCATION");
	icalcomponent_add_property (tz_comp, icalprop);
	
	if (stdidx != -1) {
		if (num_trans != 0)
			zidx = trans_idx [stdidx];
		else 
			zidx = 0;

		std_comp = icalcomponent_new (ICAL_XSTANDARD_COMPONENT);
		icalprop = icalproperty_new_tzname (types [zidx].zname);
		icalcomponent_add_property (std_comp, icalprop);

		if (dstidx != -1)
			zp_idx = trans_idx [stdidx-1]; 
		else
			zp_idx = zidx;
		/* DTSTART localtime uses TZOFFSETFROM UTC offset */
		trans = transitions [stdidx] + types [zp_idx].gmtoff;
		icaltime = icaltime_from_timet (trans, 0);
		dtstart = icaltime;
		dtstart.year = 1970;
		dtstart.minute = dtstart.second = 0;
		icalprop = icalproperty_new_dtstart (dtstart);
		icalcomponent_add_property (std_comp, icalprop);

		/* If DST changes are present use RRULE */
		if (dstidx != -1) {
			icalrecurrencetype_clear (&ical_recur);
			ical_recur.freq = ICAL_YEARLY_RECURRENCE;
			ical_recur.by_month [0] = icaltime.month;
			pos = calculate_pos (icaltime);
			pos < 0 ? (sign = -1): (sign = 1);
			ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime));
			icalprop = icalproperty_new_rrule (ical_recur);
			icalcomponent_add_property (std_comp, icalprop);

			adjust_dtstart_day_to_rrule (std_comp, ical_recur);
		}
        icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff);
        icalcomponent_add_property (std_comp, icalprop);

		icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff);
		icalcomponent_add_property (std_comp, icalprop);

		icalcomponent_add_component (tz_comp, std_comp);
	} else 
		icalerror_set_errno (ICAL_MALFORMEDDATA_ERROR);
	
	if (dstidx != -1) {
		zidx = trans_idx [dstidx];
		zp_idx = trans_idx [dstidx-1];
		dst_comp = icalcomponent_new (ICAL_XDAYLIGHT_COMPONENT);
		icalprop = icalproperty_new_tzname (types [zidx].zname);
		icalcomponent_add_property (dst_comp, icalprop);

		/* DTSTART localtime uses TZOFFSETFROM UTC offset */
		trans = transitions [dstidx] + types [zp_idx].gmtoff;
		icaltime = icaltime_from_timet (trans, 0);
		dtstart = icaltime;
		dtstart.year = 1970;
		dtstart.minute = dtstart.second = 0;
		icalprop = icalproperty_new_dtstart (dtstart);
		icalcomponent_add_property (dst_comp, icalprop);

		icalrecurrencetype_clear (&ical_recur);
		ical_recur.freq = ICAL_YEARLY_RECURRENCE;
		ical_recur.by_month [0] = icaltime.month;
		pos = calculate_pos (icaltime);
		pos < 0 ? (sign = -1): (sign = 1);
		ical_recur.by_day [0] = sign * ((abs (pos) * 8) + icaltime_day_of_week (icaltime));
		icalprop = icalproperty_new_rrule (ical_recur);
		icalcomponent_add_property (dst_comp, icalprop);

		adjust_dtstart_day_to_rrule (dst_comp, ical_recur);

		icalprop = icalproperty_new_tzoffsetfrom (types [zp_idx].gmtoff);
		icalcomponent_add_property (dst_comp, icalprop);

		icalprop = icalproperty_new_tzoffsetto (types [zidx].gmtoff);
		icalcomponent_add_property (dst_comp, icalprop);

		icalcomponent_add_component (tz_comp, dst_comp);
	}

error:
	if (f)
		fclose  (f);

	if (transitions)
		free (transitions);
	if (trans_idx)
		free (trans_idx);
	if (types) {
		for (i = 0; i < num_types; i++) 
			if (types [i].zname)
				free (types [i].zname);
		free (types);
	}
	if (znames)
		free (znames);
	free (full_path);
	if (leaps)
		free (leaps);

	return tz_comp;
}