NS_IMETHODIMP
calIcalProperty::SetValueAsIcalString(const nsACString &str)
{
    const char *kindstr =
        icalvalue_kind_to_string(icalproperty_kind_to_value_kind(icalproperty_isa(mProperty)));
    icalproperty_set_value_from_string(mProperty,
                                       PromiseFlatCString(str).get(),
                                       kindstr);
    return NS_OK;
}
Пример #2
0
const char *icalproperty_get_invitee(icalproperty *prop)
{
    const char *recip;

    if (icalproperty_isa(prop) == ICAL_VOTER_PROPERTY) {
        recip = icalproperty_get_voter(prop);
    }
    else {
        recip = icalproperty_get_attendee(prop);
    }

    return recip;
}
Пример #3
0
/*
 * Construct an XML element for an iCalendar property.
 */
static xmlNodePtr icalproperty_as_xml_element(icalproperty *prop)
{
    icalproperty_kind prop_kind;
    const char *x_name, *property_name = NULL;
    icalparameter *param;
    xmlNodePtr xprop, xparams = NULL;

    if (!prop) return NULL;

    prop_kind = icalproperty_isa(prop);
    x_name = icalproperty_get_x_name(prop);

    if (prop_kind == ICAL_X_PROPERTY && x_name)
        property_name = x_name;
    else
        property_name = icalproperty_kind_to_string(prop_kind);

    if (!property_name) {
        icalerror_warn("Got a property of an unknown kind.");
        return NULL;
    }

    /* Create property */
    xprop = xmlNewNode(NULL,
                       BAD_CAST lcase(icalmemory_tmp_copy(property_name)));


    /* Add parameters */
    for (param = icalproperty_get_first_parameter(prop, ICAL_ANY_PARAMETER);
            param != 0;
            param = icalproperty_get_next_parameter(prop, ICAL_ANY_PARAMETER)) {

        if (icalparameter_isa(param) == ICAL_VALUE_PARAMETER) continue;

        if (!xparams)
            xparams = xmlNewChild(xprop, NULL, BAD_CAST "parameters", NULL);

        xmlAddChild(xparams, icalparameter_as_xml_element(param));
    }


    /* Add value */
    icalproperty_add_value_as_xml_element(xprop, prop);

    return xprop;
}
Пример #4
0
void Todo::updateDataFromIcal() {
    assert(_ptrIcal);
    assert(icalcomponent_isa(_ptrIcal) == ICAL_VTODO_COMPONENT);

    for (icalproperty * ptrProperty = icalcomponent_get_first_property(_ptrIcal, ICAL_ANY_PROPERTY);
            ptrProperty != 0;
            ptrProperty = icalcomponent_get_next_property(_ptrIcal, ICAL_ANY_PROPERTY)) {

        icalproperty_kind propertyKind = icalproperty_isa(ptrProperty);

        switch (propertyKind) {
            case ICAL_SUMMARY_PROPERTY:     convertIcalToString(_summary, ptrProperty);         break;
            case ICAL_LOCATION_PROPERTY:    convertIcalToString(_location, ptrProperty);        break;
            case ICAL_DESCRIPTION_PROPERTY: convertIcalToString(_description, ptrProperty);     break;
            default: break;
        }
    }
}
Пример #5
0
/*
 * Determine the type (kind) of an iCalendar property value.
 */
const char *icalproperty_value_kind_as_string(icalproperty *prop)
{
    icalvalue_kind kind = ICAL_NO_VALUE;
    icalparameter *val_param;

    val_param = icalproperty_get_first_parameter(prop, ICAL_VALUE_PARAMETER);
    if (val_param) {
        /* Use the kind specified in the VALUE param */
        kind = icalparameter_value_to_value_kind(
                   icalparameter_get_value(val_param));
    }

    if (kind == ICAL_NO_VALUE) {
        icalvalue *value = icalproperty_get_value(prop);

        if (value) {
            /* Use the kind determined from the property value */
            kind = icalvalue_isa(value);
        }
    }

    if (kind == ICAL_NO_VALUE) {
        /* Use the default kind for the property */
        kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop));
    }

    switch (kind) {
    case ICAL_X_VALUE:
        return "unknown";

    case ICAL_ACTION_VALUE:
    case ICAL_CARLEVEL_VALUE:
    case ICAL_CLASS_VALUE:
    case ICAL_CMD_VALUE:
    case ICAL_METHOD_VALUE:
    case ICAL_QUERYLEVEL_VALUE:
    case ICAL_STATUS_VALUE:
    case ICAL_TRANSP_VALUE:
        return "text";

    default:
        return icalvalue_kind_to_string(kind);
    }
}
NS_IMETHODIMP
calIcalProperty::SetValue(const nsACString &str)
{
    icalvalue_kind kind = icalproperty_kind_to_value_kind(icalproperty_isa(mProperty));
    if (kind == ICAL_TEXT_VALUE) {
        icalvalue *v = icalvalue_new_text(PromiseFlatCString(str).get());
        icalproperty_set_value(mProperty, v);
    } else if (kind == ICAL_X_VALUE) {
        icalvalue *v = icalvalue_new_x(PromiseFlatCString(str).get());
        icalproperty_set_value(mProperty, v);
    } else if (kind == ICAL_ATTACH_VALUE) {
        const char *strdata = PromiseFlatCString(str).get();
        icalattach *v = icalattach_new_from_data(strdata, nullptr, nullptr);
        icalproperty_set_attach(mProperty, v);
    } else {
        icalproperty_set_value_from_string(mProperty,
                                           PromiseFlatCString(str).get(),
                                           icalvalue_kind_to_string(kind));
    }
    return NS_OK;
}
Пример #7
0
const char *get_icalcomponent_errstr(icalcomponent *ical)
{
    icalcomponent *comp;

    for (comp = icalcomponent_get_first_component(ical, ICAL_ANY_COMPONENT);
         comp;
         comp = icalcomponent_get_next_component(ical, ICAL_ANY_COMPONENT)) {
        icalproperty *prop;

        for (prop = icalcomponent_get_first_property(comp, ICAL_ANY_PROPERTY);
             prop;
             prop = icalcomponent_get_next_property(comp, ICAL_ANY_PROPERTY)) {

            if (icalproperty_isa(prop) == ICAL_XLICERROR_PROPERTY) {
                const char *errstr = icalproperty_get_xlicerror(prop);
                char propname[256];

                if (!errstr) return "Unknown iCal parsing error";

                /* Check if this is an empty property error */
                if (sscanf(errstr,
                           "No value for %s property", propname) == 1) {
                    /* Empty LOCATION is OK */
                    if (!strcasecmp(propname, "LOCATION")) continue;
                    if (!strcasecmp(propname, "COMMENT")) continue;
                    if (!strcasecmp(propname, "DESCRIPTION")) continue;
                }
                else {
                    /* Ignore unknown property errors */
                    if (!strncmp(errstr, "Parse error in property name", 28))
                        continue;
                }

                return errstr;
            }
        }
    }

    return NULL;
}
Пример #8
0
/*
 * Add the proper XML element for an iCalendar value.
 */
static void icalproperty_add_value_as_xml_element(xmlNodePtr xprop,
        icalproperty *prop)

{
    const char *type, *str = NULL;
    xmlNodePtr xtype;
    const icalvalue *value;
    char buf[40];

    /* Add type */
    type = lcase(icalmemory_tmp_copy(
                     icalproperty_value_kind_as_string(prop)));
    xtype = xmlNewChild(xprop, NULL, BAD_CAST type, NULL);


    /* Add value */
    value = icalproperty_get_value(prop);

    switch (icalvalue_isa(value)) {
    case ICAL_DATE_VALUE:
        str = icaltime_as_iso_string(icalvalue_get_date(value));
        break;

    case ICAL_DATETIME_VALUE:
        str = icaltime_as_iso_string(icalvalue_get_datetime(value));
        break;

    case ICAL_DATETIMEPERIOD_VALUE: {
        struct icaldatetimeperiodtype dtp =
            icalvalue_get_datetimeperiod(value);

        if (!icaltime_is_null_time(dtp.time)) {
            str = icaltime_as_iso_string(dtp.time);
            break;
        }
        else {
            icalperiodtype_add_as_xml_element(xtype, dtp.period);
            return;
        }
    }

    case ICAL_GEO_VALUE: {
        struct icalgeotype geo = icalvalue_get_geo(value);

        snprintf(buf, sizeof(buf), "%f", geo.lat);
        xmlNewTextChild(xtype, NULL, BAD_CAST "latitude", BAD_CAST buf);
        snprintf(buf, sizeof(buf), "%f", geo.lon);
        xmlNewTextChild(xtype, NULL, BAD_CAST "longitude", BAD_CAST buf);
        return;
    }

    case ICAL_PERIOD_VALUE:
        icalperiodtype_add_as_xml_element(xtype, icalvalue_get_period(value));
        return;

    case ICAL_RECUR_VALUE: {
        struct icalrecurrencetype recur = icalvalue_get_recur(value);

        icalrecurrencetype_add_as_xxx(&recur, xtype, NULL,
                                      &icalrecur_add_string_as_xml_element);
        return;
    }

    case ICAL_REQUESTSTATUS_VALUE: {
        struct icalreqstattype stat = icalvalue_get_requeststatus(value);

        if (!stat.desc) stat.desc = icalenum_reqstat_desc(stat.code);

        snprintf(buf, sizeof(buf), "%u.%u",
                 icalenum_reqstat_major(stat.code),
                 icalenum_reqstat_minor(stat.code));
        xmlNewTextChild(xtype, NULL, BAD_CAST "code", BAD_CAST buf);
        xmlNewTextChild(xtype, NULL, BAD_CAST "description", BAD_CAST stat.desc);
        if (stat.debug)
            xmlNewTextChild(xtype, NULL, BAD_CAST "data", BAD_CAST stat.debug);

        return;
    }

    case ICAL_TRIGGER_VALUE: {
        struct icaltriggertype trig = icalvalue_get_trigger(value);

        if (!icaltime_is_null_time(trig.time))
            str = icaltime_as_iso_string(trig.time);
        else
            str = icaldurationtype_as_ical_string(trig.duration);
        break;
    }

    case ICAL_UTCOFFSET_VALUE:
        str = icalvalue_utcoffset_as_iso_string(value);
        break;

    default:
        str = icalvalue_as_ical_string(value);

        switch (icalproperty_isa(prop)) {
        case ICAL_CATEGORIES_PROPERTY:
        case ICAL_RESOURCES_PROPERTY:
        case ICAL_POLLPROPERTIES_PROPERTY:
            if (strchr(str, ',')) {
                /* Handle multi-valued properties */
                tok_t tok;

                tok_init(&tok, str, ",", TOK_TRIMLEFT|TOK_TRIMRIGHT|TOK_EMPTY);
                str = tok_next(&tok);
                xmlAddChild(xtype, xmlNewText(BAD_CAST str));

                while ((str = tok_next(&tok))) {
                    if (*str) {
                        xtype = xmlNewChild(xprop, NULL, BAD_CAST type, NULL);
                        xmlAddChild(xtype, xmlNewText(BAD_CAST str));
                    }
                }
                tok_fini(&tok);
                return;
            }

        default:
            break;
        }

        break;
    }

    if (str) xmlAddChild(xtype, xmlNewText(BAD_CAST str));
}
Пример #9
0
char *icallangbind_property_eval_string_r(icalproperty *prop, char *sep)
{
    char tmp[25];
    size_t buf_size = 1024;
    char *buf;
    char *buf_ptr;
    icalparameter *param;

    icalvalue *value;

    if (prop == 0) {
        return 0;
    }

    buf = icalmemory_new_buffer(buf_size);
    buf_ptr = buf;

    APPENDS("{ ");

    value = icalproperty_get_value(prop);

    APPENDS(" 'name' ");
    APPENDS(sep);
    APPENDC('\'');
    APPENDS(icalproperty_kind_to_string(icalproperty_isa(prop)));
    APPENDC('\'');

    if (value) {
        APPENDS(", 'value_type' ");
        APPENDS(sep);
        APPENDC('\'');
        APPENDS(icalvalue_kind_to_string(icalvalue_isa(value)));
        APPENDC('\'');
    }

    APPENDS(", 'pid' ");
    APPENDS(sep);
    APPENDC('\'');
    snprintf(tmp, 25, "%p", prop);
    APPENDS(tmp);
    APPENDC('\'');

    if (value) {
        switch (icalvalue_isa(value)) {

        case ICAL_ATTACH_VALUE:
        case ICAL_BINARY_VALUE:
        case ICAL_NO_VALUE:{
                icalerror_set_errno(ICAL_INTERNAL_ERROR);
                break;
            }

        default:
            {
                char *str = icalvalue_as_ical_string_r(value);
                char *copy = (char *)malloc(strlen(str) + 1);

                const char *i;
                char *j;

                if (copy == 0) {
                    icalerror_set_errno(ICAL_NEWFAILED_ERROR);
                    break;
                }
                /* Remove any newlines */

                for (j = copy, i = str; *i != 0; j++, i++) {
                    if (*i == '\n') {
                        i++;
                    }
                    *j = *i;
                }

                *j = 0;

                APPENDS(", 'value'");
                APPENDS(sep);
                APPENDC('\'');
                APPENDS(copy);
                APPENDC('\'');

                free(copy);
                free(str);
                break;
            }
        }
    }

    /* Add Parameters */

    for (param = icalproperty_get_first_parameter(prop, ICAL_ANY_PARAMETER);
         param != 0; param = icalproperty_get_next_parameter(prop, ICAL_ANY_PARAMETER)) {

        char *copy = icalparameter_as_ical_string_r(param);
        char *v;

        if (copy == 0) {
            icalerror_set_errno(ICAL_NEWFAILED_ERROR);
            continue;
        }

        v = strchr(copy, '=');

        if (v == 0) {
            free(copy);
            continue;
        }

        *v = 0;

        v++;

        APPENDS(", ");
        APPENDC('\'');
        APPENDS(copy);
        APPENDC('\'');
        APPENDS(sep);
        APPENDC('\'');
        APPENDS(v);
        APPENDC('\'');
        free(copy);
    }

    APPENDC('}');

    return buf;
}
Пример #10
0
/*
 * Construct a JSON array for an iCalendar property.
 */
static json_t *icalproperty_as_json_array(icalproperty *prop)
{
    icalproperty_kind prop_kind;
    const char *x_name, *property_name = NULL;
    icalparameter *param;
    const char *type = NULL;
    const icalvalue *value;
    json_t *jprop, *jparams;

    if (!prop) return NULL;

    prop_kind = icalproperty_isa(prop);
    x_name = icalproperty_get_x_name(prop);

    if (prop_kind == ICAL_X_PROPERTY && x_name)
        property_name = x_name;
    else
        property_name = icalproperty_kind_to_string(prop_kind);

    if (!property_name) {
        icalerror_warn("Got a property of an unknown kind.");
        return NULL;
    }

    /* Create property array */
    jprop = json_array();


    /* Add property name */
    json_array_append_new(jprop,
                          json_string(lcase(icalmemory_tmp_copy(property_name))));


    /* Add parameters */
    jparams = json_object();
    for (param = icalproperty_get_first_parameter(prop, ICAL_ANY_PARAMETER);
         param != 0;
         param = icalproperty_get_next_parameter(prop, ICAL_ANY_PARAMETER)) {

        if (icalparameter_isa(param) == ICAL_VALUE_PARAMETER) continue;

        icalparameter_as_json_object_member(param, jparams);
    }
    json_array_append_new(jprop, jparams);


    /* Add type */
    type = icalproperty_value_kind_as_string(prop);
    json_array_append_new(jprop, json_string(lcase(icalmemory_tmp_copy(type))));


    /* Add value */
    value = icalproperty_get_value(prop);
    if (value) {
        switch (icalproperty_isa(prop)) {
        case ICAL_CATEGORIES_PROPERTY:
        case ICAL_RESOURCES_PROPERTY:
        case ICAL_POLLPROPERTIES_PROPERTY:
            if (icalvalue_isa(value) == ICAL_TEXT_VALUE) {
                /* Handle multi-valued properties */
                const char *str = icalvalue_as_ical_string(value);
                tok_t tok;

                tok_init(&tok, str, ",", TOK_TRIMLEFT|TOK_TRIMRIGHT|TOK_EMPTY);
                while ((str = tok_next(&tok))) {
                    if (*str) json_array_append_new(jprop, json_string(str));
                }
                tok_fini(&tok);
                break;
            }

        default:
            json_array_append_new(jprop, icalvalue_as_json_object(value));
            break;
        }
    }

    return jprop;
}
Пример #11
0
int icalgauge_compare_recurse(icalcomponent* comp, icalcomponent* gauge)
{
    int pass = 1,localpass = 0;
    icalproperty *p;
    icalcomponent *child,*subgauge; 
    icalcomponent_kind gaugekind, compkind;

    icalerror_check_arg_rz( (comp!=0), "comp");
    icalerror_check_arg_rz( (gauge!=0), "gauge");

    gaugekind = icalcomponent_isa(gauge);
    compkind = icalcomponent_isa(comp);

    if( ! (gaugekind == compkind || gaugekind == ICAL_ANY_COMPONENT) ){
	return 0;
    }   

    /* Test properties. For each property in the gauge, search through
       the component for a similar property. If one is found, compare
       the two properties value with the comparison specified in the
       gauge with the X-LIC-COMPARETYPE parameter */
    
    for(p = icalcomponent_get_first_property(gauge,ICAL_ANY_PROPERTY);
	p != 0;
	p = icalcomponent_get_next_property(gauge,ICAL_ANY_PROPERTY)){
	
	icalproperty* targetprop; 
	icalparameter* compareparam;
	icalparameter_xliccomparetype compare;
	int rel; /* The relationship between the gauge and target values.*/
	
	/* Extract the comparison type from the gauge. If there is no
	   comparison type, assume that it is "EQUAL" */
	
	compareparam = icalproperty_get_first_parameter(
	    p,
	    ICAL_XLICCOMPARETYPE_PARAMETER);
	
	if (compareparam!=0){
	    compare = icalparameter_get_xliccomparetype(compareparam);
	} else {
	    compare = ICAL_XLICCOMPARETYPE_EQUAL;
	}
	
	/* Find a property in the component that has the same type
	   as the gauge property. HACK -- multiples of a single
	   property type in the gauge will match only the first
	   instance in the component */
	
	targetprop = icalcomponent_get_first_property(comp,
						      icalproperty_isa(p));
	
	if(targetprop != 0){
	
	    /* Compare the values of the gauge property and the target
	       property */
	    
	    rel = icalvalue_compare(icalproperty_get_value(p),
				    icalproperty_get_value(targetprop));
	    
	    /* Now see if the comparison is equavalent to the comparison
	       specified in the gauge */
	    
	    if (rel == compare){ 
		localpass++; 
	    } else if (compare == ICAL_XLICCOMPARETYPE_LESSEQUAL && 
		       ( rel == ICAL_XLICCOMPARETYPE_LESS ||
			 rel == ICAL_XLICCOMPARETYPE_EQUAL)) {
		localpass++;
	    } else if (compare == ICAL_XLICCOMPARETYPE_GREATEREQUAL && 
		       ( rel == ICAL_XLICCOMPARETYPE_GREATER ||
			 rel == ICAL_XLICCOMPARETYPE_EQUAL)) {
		localpass++;
	    } else if (compare == ICAL_XLICCOMPARETYPE_NOTEQUAL && 
		       ( rel == ICAL_XLICCOMPARETYPE_GREATER ||
			 rel == ICAL_XLICCOMPARETYPE_LESS)) {
		localpass++;
	    } else {
		localpass = 0;
	    }
	    
	    pass = pass && (localpass>0);
	}
    }
    
    /* Test subcomponents. Look for a child component that has a
       counterpart in the gauge. If one is found, recursively call
       icaldirset_test */
    
    for(subgauge = icalcomponent_get_first_component(gauge,ICAL_ANY_COMPONENT);
	subgauge != 0;
	subgauge = icalcomponent_get_next_component(gauge,ICAL_ANY_COMPONENT)){
	
	gaugekind = icalcomponent_isa(subgauge);

	if (gaugekind == ICAL_ANY_COMPONENT){
	    child = icalcomponent_get_first_component(comp,ICAL_ANY_COMPONENT);
	} else {
	    child = icalcomponent_get_first_component(comp,gaugekind);
	}
	
	if(child !=0){
	    localpass = icalgauge_compare_recurse(child,subgauge);
	    pass = pass && localpass;
	} else {
	    pass = 0;
	}
    }
    
    return pass;   
}
Пример #12
0
static void
icaltimezone_expand_vtimezone		(icalcomponent	*comp,
					 int		 end_year,
					 icalarray	*changes)
{
    icaltimezonechange change;
    icalproperty *prop;
    struct icaltimetype dtstart, occ;
    struct icalrecurrencetype rrule;
    icalrecur_iterator* rrule_iterator;
    struct icaldatetimeperiodtype rdate;
    int found_dtstart = 0, found_tzoffsetto = 0, found_tzoffsetfrom = 0;
    int has_recurrence = 0;

    /* First we check if it is a STANDARD or DAYLIGHT component, and
       just return if it isn't. */
    if (icalcomponent_isa (comp) == ICAL_XSTANDARD_COMPONENT)
	change.is_daylight = 0;
    else if (icalcomponent_isa (comp) == ICAL_XDAYLIGHT_COMPONENT)
	change.is_daylight = 1;
    else 
	return;

    /* Step through each of the properties to find the DTSTART,
       TZOFFSETFROM and TZOFFSETTO. We can't expand recurrences here
       since we need these properties before we can do that. */
    prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY);
    while (prop) {
	switch (icalproperty_isa (prop)) {
	case ICAL_DTSTART_PROPERTY:
	    dtstart = icalproperty_get_dtstart (prop);
	    found_dtstart = 1;
	    break;
	case ICAL_TZOFFSETTO_PROPERTY:
	    change.utc_offset = icalproperty_get_tzoffsetto (prop);
	    /*printf ("Found TZOFFSETTO: %i\n", change.utc_offset);*/
	    found_tzoffsetto = 1;
	    break;
	case ICAL_TZOFFSETFROM_PROPERTY:
	    change.prev_utc_offset = icalproperty_get_tzoffsetfrom (prop);
	    /*printf ("Found TZOFFSETFROM: %i\n", change.prev_utc_offset);*/
	    found_tzoffsetfrom = 1;
	    break;
	case ICAL_RDATE_PROPERTY:
	case ICAL_RRULE_PROPERTY:
	    has_recurrence = 1;
	    break;
	default:
	    /* Just ignore any other properties. */
	    break;
	}

	prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY);
    }

    /* If we didn't find a DTSTART, TZOFFSETTO and TZOFFSETFROM we have to
       ignore the component. FIXME: Add an error property? */
    if (!found_dtstart || !found_tzoffsetto || !found_tzoffsetfrom)
	return;

#if 0
    printf ("\n Expanding component DTSTART (Y/M/D): %i/%i/%i %i:%02i:%02i\n",
	    dtstart.year, dtstart.month, dtstart.day,
	    dtstart.hour, dtstart.minute, dtstart.second);
#endif

    /* If the STANDARD/DAYLIGHT component has no recurrence data, we just add
       a single change for the DTSTART. */
    if (!has_recurrence) {
	change.year   = dtstart.year;
	change.month  = dtstart.month;
	change.day    = dtstart.day;
	change.hour   = dtstart.hour;
	change.minute = dtstart.minute;
	change.second = dtstart.second;

	/* Convert to UTC. */
	icaltimezone_adjust_change (&change, 0, 0, 0, -change.prev_utc_offset);

#if 0
	printf ("  Appending single DTSTART (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n",
		change.year, change.month, change.day,
		change.hour, change.minute, change.second);
#endif

	/* Add the change to the array. */
	icalarray_append (changes, &change);
	return;
    }

    /* The component has recurrence data, so we expand that now. */
    prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY);
    while (prop) {
#if 0
	printf ("Expanding property...\n");
#endif
	switch (icalproperty_isa (prop)) {
	case ICAL_RDATE_PROPERTY:
	    rdate = icalproperty_get_rdate (prop);
	    change.year   = rdate.time.year;
	    change.month  = rdate.time.month;
	    change.day    = rdate.time.day;
	    /* RDATEs with a DATE value inherit the time from
	       the DTSTART. */
	    if (icaltime_is_date(rdate.time)) {
		change.hour   = dtstart.hour;
		change.minute = dtstart.minute;
		change.second = dtstart.second;
	    } else {
		change.hour   = rdate.time.hour;
		change.minute = rdate.time.minute;
		change.second = rdate.time.second;

		/* The spec was a bit vague about whether RDATEs were in local
		   time or UTC so we support both to be safe. So if it is in
		   UTC we have to add the UTC offset to get a local time. */
		if (!icaltime_is_utc(rdate.time))
		    icaltimezone_adjust_change (&change, 0, 0, 0,
						-change.prev_utc_offset);
	    }

#if 0
	    printf ("  Appending RDATE element (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n",
		    change.year, change.month, change.day,
		    change.hour, change.minute, change.second);
#endif

	    icalarray_append (changes, &change);
	    break;
	case ICAL_RRULE_PROPERTY:
	    rrule = icalproperty_get_rrule (prop);

	    /* If the rrule UNTIL value is set and is in UTC, we convert it to
	       a local time, since the recurrence code has no way to convert
	       it itself. */
	    if (!icaltime_is_null_time (rrule.until) && rrule.until.is_utc) {
#if 0
		printf ("  Found RRULE UNTIL in UTC.\n");
#endif

		/* To convert from UTC to a local time, we use the TZOFFSETFROM
		   since that is the offset from UTC that will be in effect
		   when each of the RRULE occurrences happens. */
		icaltime_adjust (&rrule.until, 0, 0, 0,
				 change.prev_utc_offset);
		rrule.until.is_utc = 0;
	    }

	    rrule_iterator = icalrecur_iterator_new (rrule, dtstart);
	    for (;;) {
		occ = icalrecur_iterator_next (rrule_iterator);
		if (occ.year > end_year || icaltime_is_null_time (occ))
		    break;

		change.year   = occ.year;
		change.month  = occ.month;
		change.day    = occ.day;
		change.hour   = occ.hour;
		change.minute = occ.minute;
		change.second = occ.second;

#if 0
		printf ("  Appending RRULE element (Y/M/D): %i/%02i/%02i %i:%02i:%02i\n",
			change.year, change.month, change.day,
			change.hour, change.minute, change.second);
#endif

		icaltimezone_adjust_change (&change, 0, 0, 0,
					    -change.prev_utc_offset);

		icalarray_append (changes, &change);
	    }

	    icalrecur_iterator_free (rrule_iterator);
	    break;
	default:
	    break;
	}

	prop = icalcomponent_get_next_property (comp, ICAL_ANY_PROPERTY);
    }
}
Пример #13
0
static void ical2exchange_get_properties(struct ical2exchange *ical2exchange, icalcomponent *vevent){
	icalproperty *icalProp = NULL;
	icalproperty *prop = NULL;
	const char *xname;
	enum icalproperty_kind propType;

	icalProp=icalcomponent_get_first_property(vevent, ICAL_ANY_PROPERTY);
	
	while(icalProp!=0){
		propType=icalproperty_isa(icalProp);
		switch (propType){
			case ICAL_ATTACH_PROPERTY:
				if(!ical2exchange->attachEvent){
					ical2exchange->attachEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				icalcomponent_add_property(ical2exchange->attachEvent, prop);
				break;
			case ICAL_ATTENDEE_PROPERTY:
				if(!ical2exchange->attendeeEvent){
					ical2exchange->attendeeEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				icalcomponent_add_property(ical2exchange->attendeeEvent, prop);
				break;
			case ICAL_CATEGORIES_PROPERTY:
				if(!ical2exchange->categoriesEvent){
					ical2exchange->categoriesEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				icalcomponent_add_property(ical2exchange->categoriesEvent, prop);
				break;
			case ICAL_CLASS_PROPERTY:
				ical2exchange->classProp=icalProp;
				break;
			case ICAL_COMMENT_PROPERTY:
				ical2exchange->commentProp=icalProp;
				break;
			case ICAL_CONTACT_PROPERTY:
				if(!ical2exchange->contactEvent){
					ical2exchange->contactEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				icalcomponent_add_property(ical2exchange->contactEvent, prop);
				break;
			case ICAL_CREATED_PROPERTY:
				break;
			case ICAL_DESCRIPTION_PROPERTY:
				ical2exchange->descriptionProp=icalProp;
				break;
			case ICAL_DTEND_PROPERTY:
				ical2exchange->dtendProp=icalProp;
				break;
			case ICAL_DTSTAMP_PROPERTY:
				ical2exchange->dtstampProp=icalProp;
				break;
			case ICAL_DTSTART_PROPERTY:
				ical2exchange->dtstartProp=icalProp;
				break;
			case ICAL_DURATION_PROPERTY:
				ical2exchange->durationProp=icalProp;
				break;
			case ICAL_EXDATE_PROPERTY:
				if(!ical2exchange->exdateEvent){
					ical2exchange->exdateEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				ical2exchange->exdateCount ++;
				icalcomponent_add_property(ical2exchange->exdateEvent, prop);
				break;
			case ICAL_LASTMODIFIED_PROPERTY:
				break;
			case ICAL_LOCATION_PROPERTY:
				ical2exchange->locationProp=icalProp;
				break;
			case ICAL_ORGANIZER_PROPERTY:
				//TODO: figure out how to MS-OXOABK
				ical2exchange->organizerProp=icalProp;
				break;
			case ICAL_PRIORITY_PROPERTY:
				ical2exchange->priorityProp=icalProp;
				break;
			case ICAL_RDATE_PROPERTY:
				if(!ical2exchange->rdateEvent){
					ical2exchange->rdateEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				ical2exchange->rdateCount ++;
				icalcomponent_add_property(ical2exchange->rdateEvent, prop);
				break;
			case ICAL_RECURRENCEID_PROPERTY:
				ical2exchange->recurrenceidProp=icalProp;
				break;
			case ICAL_RESOURCES_PROPERTY:
				if(!ical2exchange->resourcesEvent){
					ical2exchange->resourcesEvent=icalcomponent_new_vevent();
				}
				prop = icalproperty_new_clone(icalProp);
				icalcomponent_add_property(ical2exchange->resourcesEvent, prop);
				break;
			case ICAL_RRULE_PROPERTY:
				ical2exchange->rruleProp=icalProp;
				break;
			case ICAL_SEQUENCE_PROPERTY:
				ical2exchange->sequenceProp=icalProp;
				break;
			case ICAL_STATUS_PROPERTY:
				ical2exchange->statusProp=icalProp;
				break;
			case ICAL_SUMMARY_PROPERTY:
				ical2exchange->summaryProp=icalProp;
				break;
			case ICAL_TRANSP_PROPERTY:
				ical2exchange->transpProp=icalProp;
				break;
			case ICAL_UID_PROPERTY:
				//TODO
				ical2exchange->uidProp=icalProp;
				break;
		 	case ICAL_X_PROPERTY: 
				xname=icalproperty_get_x_name(icalProp);
				if(!strcmp(xname,"X-MICROSOFT-CDO-BUSYSTATUS")){
					ical2exchange->x_busystatusProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-BUSYSTATUS")){
					ical2exchange->x_busystatusProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-APPT-SEQUENCE")){
					ical2exchange->x_sequenceProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-IMPORTANCE")){
					ical2exchange->x_importanceProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-IMPORTANCE")){
					ical2exchange->x_importanceProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-INTENDEDSTATUS")){
					ical2exchange->x_intendedProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-MSNCALENDAR-INTENDEDSTATUS")){
					ical2exchange->x_intendedProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNERAPPTID")){
					ical2exchange->x_ownerapptidProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-ATTENDEE-CRITICAL-CHANGE")){
					ical2exchange->x_attendeecriticalchangeProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-OWNER-CRITICAL-CHANGE")){
					ical2exchange->x_ownercriticalchangeProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-CDO-REPLYTIME")){
					ical2exchange->x_replytimeProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-DISALLOW-COUNTER")){
					ical2exchange->x_disallowcounterProp=icalProp;
				} else if(!strcmp(xname,"X-MICROSOFT-ISDRAFT")){
					ical2exchange->x_isdraftProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-ALLOWEXTERNCHECK")){
					ical2exchange->x_allowexterncheckProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-APPTLASTSEQUENCE")){
					ical2exchange->x_apptlastsequenceProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-APPTSEQTIME")){
					ical2exchange->x_apptseqtimeProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-AUTOFILLLOCATION")){
					ical2exchange->x_autofilllocationProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-AUTOSTARTCHECK")){
					ical2exchange->x_autostartcheckProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-CONFCHECK")){
					ical2exchange->x_confcheckProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-COLLABORATEDDOC")){
					ical2exchange->x_collaborateddocProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-CONFTYPE")){
					ical2exchange->x_conftypeProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-MWSURL")){
					ical2exchange->x_mwsurlProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-NETSHOWURL")){
					ical2exchange->x_netshowurlProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-ONLINEPASSWORD")){
					ical2exchange->x_onlinepasswordProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-ORGALIAS")){
					ical2exchange->x_orgaliasProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-ORIGINALEND")){
					ical2exchange->x_originalendProp=icalProp;
				} else if(!strcmp(xname,"X-MS-OLK-ORIGINALSTART")){
					ical2exchange->x_originalstartProp=icalProp;
				}
				
				break;
			default:
				break;
		}
		icalProp=icalcomponent_get_next_property(vevent, ICAL_ANY_PROPERTY);
	}
	
	ical2exchange->valarmEvent = icalcomponent_get_first_component(vevent,ICAL_VALARM_COMPONENT);
	
}
Пример #14
0
icalcomponent *icalparser_add_line(icalparser *parser, char *line)
{
    char *str;
    char *end;
    int pcount = 0;
    int vcount = 0;
    icalproperty *prop;
    icalproperty_kind prop_kind;
    icalvalue *value;
    icalvalue_kind value_kind = ICAL_NO_VALUE;

    icalerror_check_arg_rz((parser != 0), "parser");

    if (line == 0) {
        parser->state = ICALPARSER_ERROR;
        return 0;
    }

    if (line_is_blank(line) == 1) {
        return 0;
    }

    /* Begin by getting the property name at the start of the line. The
       property name may end up being "BEGIN" or "END" in which case it
       is not really a property, but the marker for the start or end of
       a component */

    end = 0;
    str = parser_get_prop_name(line, &end);

    if (str == 0 || *str == '\0') {
        /* Could not get a property name */
        icalcomponent *tail = pvl_data(pvl_tail(parser->components));

        if (tail) {
            insert_error(
                tail, line,
                "Got a data line, but could not find a property name or component begin tag",
                ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
        }
        tail = 0;
        parser->state = ICALPARSER_ERROR;
        icalmemory_free_buffer(str);
        str = NULL;
        return 0;
    }

    /**********************************************************************
     * Handle begin and end of components
     **********************************************************************/
    /* If the property name is BEGIN or END, we are actually
       starting or ending a new component */

    if (strcasecmp(str, "BEGIN") == 0) {
        icalcomponent *c;
        icalcomponent_kind comp_kind;

        parser->level++;
        icalmemory_free_buffer(str);
        str = parser_get_next_value(end, &end, value_kind);

        comp_kind = icalenum_string_to_component_kind(str);

        c = icalcomponent_new(comp_kind);

        if (c == 0) {
            c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
            insert_error(c, str, "Parse error in component name",
                         ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
        }

        pvl_push(parser->components, c);

        parser->state = ICALPARSER_BEGIN_COMP;

        icalmemory_free_buffer(str);
        str = NULL;
        return 0;

    } else if (strcasecmp(str, "END") == 0) {
        icalcomponent *tail;

        parser->level--;
        icalmemory_free_buffer(str);
        str = parser_get_next_value(end, &end, value_kind);

        /* Pop last component off of list and add it to the second-to-last */
        parser->root_component = pvl_pop(parser->components);

        tail = pvl_data(pvl_tail(parser->components));

        if (tail != 0) {
            icalcomponent_add_component(tail, parser->root_component);
        }

        tail = 0;
        icalmemory_free_buffer(str);
        str = NULL;

        if (parser->level < 0) {
            // Encountered an END before any BEGIN, this must be invalid data
            icalerror_warn("Encountered END before BEGIN");

            parser->state = ICALPARSER_ERROR;
            parser->level = 0;
            return 0;
        } else if (parser->level == 0) {
            /* Return the component if we are back to the 0th level */
            icalcomponent *rtrn;

            if (pvl_count(parser->components) != 0) {
                /* There are still components on the stack -- this means
                   that one of them did not have a proper "END" */
                pvl_push(parser->components, parser->root_component);
                (void)icalparser_clean(parser); /* may reset parser->root_component */
            }

            assert(pvl_count(parser->components) == 0);

            parser->state = ICALPARSER_SUCCESS;
            rtrn = parser->root_component;
            parser->root_component = 0;
            return rtrn;

        } else {
            parser->state = ICALPARSER_END_COMP;
            return 0;
        }
    }

    /* There is no point in continuing if we have not seen a
       component yet */

    if (pvl_data(pvl_tail(parser->components)) == 0) {
        parser->state = ICALPARSER_ERROR;
        icalmemory_free_buffer(str);
        str = NULL;
        return 0;
    }

    /**********************************************************************
     * Handle property names
     **********************************************************************/

    /* At this point, the property name really is a property name,
       (Not a component name) so make a new property and add it to
       the component */

    prop_kind = icalproperty_string_to_kind(str);

    prop = icalproperty_new(prop_kind);

    if (prop != 0) {
        icalcomponent *tail = pvl_data(pvl_tail(parser->components));

        if (prop_kind == ICAL_X_PROPERTY) {
            icalproperty_set_x_name(prop, str);
        }

        icalcomponent_add_property(tail, prop);

        /* Set the value kind for the default for this type of
           property. This may be re-set by a VALUE parameter */
        value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop));

    } else {
        icalcomponent *tail = pvl_data(pvl_tail(parser->components));

        insert_error(tail, str, "Parse error in property name",
                     ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);

        tail = 0;
        parser->state = ICALPARSER_ERROR;
        icalmemory_free_buffer(str);
        str = NULL;
        return 0;
    }

    icalmemory_free_buffer(str);
    str = NULL;

    /**********************************************************************
     * Handle parameter values
     **********************************************************************/

    /* Now, add any parameters to the last property */

    while (pcount < MAXIMUM_ALLOWED_PARAMETERS) {
        if (*(end - 1) == ':') {
            /* if the last separator was a ":" and the value is a
               URL, icalparser_get_next_parameter will find the
               ':' in the URL, so better break now. */
            break;
        }

        icalmemory_free_buffer(str);
        str = parser_get_next_parameter(end, &end);
        strstriplt(str);
        if (str != 0) {
            char *name_heap = 0;
            char *pvalue_heap = 0;
            char name_stack[TMP_BUF_SIZE];
            char pvalue_stack[TMP_BUF_SIZE];
            char *name = name_stack;
            char *pvalue = pvalue_stack;

            icalparameter *param = 0;
            icalparameter_kind kind;
            icalcomponent *tail = pvl_data(pvl_tail(parser->components));

            if (!parser_get_param_name_stack(str, name_stack, sizeof(name_stack),
                                             pvalue_stack, sizeof(pvalue_stack))) {
                name_heap = parser_get_param_name_heap(str, &pvalue_heap);

                name = name_heap;
                pvalue = pvalue_heap;

                if (name_heap == 0) {
                    /* 'tail' defined above */
                    insert_error(tail, str, "Cant parse parameter name",
                                 ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
                    tail = 0;
                    break;
                }
            }

            kind = icalparameter_string_to_kind(name);

            if (kind == ICAL_X_PARAMETER) {
                param = icalparameter_new(ICAL_X_PARAMETER);
                if (param != 0) {
                    icalparameter_set_xname(param, name);
                    icalparameter_set_xvalue(param, pvalue);
                }
            } else if (kind == ICAL_IANA_PARAMETER) {
                ical_unknown_token_handling tokHandlingSetting =
                    ical_get_unknown_token_handling_setting();
                if (tokHandlingSetting == ICAL_DISCARD_TOKEN) {
                    if (name_heap) {
                        icalmemory_free_buffer(name_heap);
                        name_heap = 0;
                    }
                    if (pvalue_heap) {
                        icalmemory_free_buffer(pvalue_heap);
                        pvalue_heap = 0;
                    }
                    continue;
                }

                param = icalparameter_new(ICAL_IANA_PARAMETER);

                if (param != 0) {
                    icalparameter_set_xname(param, name);
                    icalparameter_set_xvalue(param, pvalue);
                }
            } else if (kind == ICAL_TZID_PARAMETER && *(end - 1) != ';') {
                /*
                   Special case handling for TZID to work around invalid incoming data.
                   For example, Google Calendar will send back stuff like this:
                   DTSTART;TZID=GMT+05:30:20120904T020000

                   In this case we read to the next semicolon or the last colon rather
                   than the first colon.  This way the TZID will become GMT+05:30 rather
                   than trying to parse the date-time as 30:20120904T020000.

                   This also handles properties that look like this:
                   DTSTART;TZID=GMT+05:30;VALUE=DATE-TIME:20120904T020000
                 */
                char *lastColon = 0;
                char *nextColon = end;
                char *nextSemicolon = parser_get_next_char(';', end, 1);

                /* Find the last colon in the line */
                do {
                    nextColon = parser_get_next_char(':', nextColon, 1);

                    if (nextColon) {
                        lastColon = nextColon;
                    }
                } while (nextColon);

                if (lastColon && nextSemicolon && nextSemicolon < lastColon) {
                    /*
                       Ensures that we don't read past a semicolon

                       Handles the following line:
                       DTSTART;TZID=GMT+05:30;VALUE=DATE-TIME:20120904T020000
                     */
                    lastColon = nextSemicolon;
                }

                /*
                   Rebuild str so that it includes everything up to the next semicolon
                   or the last colon. So given the above example, str will go from
                   "TZID=GMT+05" to "TZID=GMT+05:30"
                 */
                if (lastColon && *(lastColon + 1) != 0) {
                    char *strStart = line + strlen(name) + 2;

                    end = lastColon + 1;

                    icalmemory_free_buffer(str);
                    str = make_segment(strStart, end - 1);
                }

                /* Reparse the parameter name and value with the new segment */
                if (!parser_get_param_name_stack(str, name_stack, sizeof(name_stack),
                                                 pvalue_stack, sizeof(pvalue_stack))) {
                    if (pvalue_heap) {
                        icalmemory_free_buffer(pvalue_heap);
                        pvalue_heap = 0;
                        pvalue = 0;
                    }
                    if (name_heap) {
                        icalmemory_free_buffer(name_heap);
                        name = 0;
                    }
                    name_heap = parser_get_param_name_heap(str, &pvalue_heap);
                    pvalue = pvalue_heap;
                }
                param = icalparameter_new_from_value_string(kind, pvalue);
            } else if (kind != ICAL_NO_PARAMETER) {
                param = icalparameter_new_from_value_string(kind, pvalue);
            } else {
                /* Error. Failed to parse the parameter */
                /* 'tail' defined above */

                /* Change for mozilla */
                /* have the option of being flexible towards unsupported parameters */
#if ICAL_ERRORS_ARE_FATAL == 1
                insert_error(tail, str, "Cant parse parameter name",
                             ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
                tail = 0;
                parser->state = ICALPARSER_ERROR;
                if (pvalue_heap) {
                    icalmemory_free_buffer(pvalue_heap);
                    pvalue = 0;
                }
                if (name_heap) {
                    icalmemory_free_buffer(name_heap);
                    name = 0;
                }
                icalmemory_free_buffer(str);
                str = NULL;
                return 0;
#else
                if (name_heap) {
                    icalmemory_free_buffer(name_heap);
                    name_heap = 0;
                }
                if (pvalue_heap) {
                    icalmemory_free_buffer(pvalue_heap);
                    pvalue_heap = 0;
                }
                icalmemory_free_buffer(str);
                str = NULL;
                continue;
#endif
            }

            if (pvalue_heap) {
                icalmemory_free_buffer(pvalue_heap);
                pvalue_heap = 0;
            }

            if (name_heap) {
                icalmemory_free_buffer(name_heap);
                name_heap = 0;
            }

            if (param == 0) {
                /* 'tail' defined above */
                insert_error(tail, str, "Cant parse parameter value",
                             ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);

                tail = 0;
                parser->state = ICALPARSER_ERROR;

                icalmemory_free_buffer(str);
                str = NULL;

                continue;
            }

            /* If it is a VALUE parameter, set the kind of value */
            if (icalparameter_isa(param) == ICAL_VALUE_PARAMETER) {
                value_kind =
                    (icalvalue_kind)icalparameter_value_to_value_kind(
                        icalparameter_get_value(param));

                if (!icalproperty_value_kind_is_valid(prop_kind, value_kind)) {

                    /* Ooops, invalid VALUE parameter, so reset the value_kind */

                    const char *err_str = "Invalid VALUE type for property";
                    const char *prop_str = icalproperty_kind_to_string(prop_kind);
                    size_t tmp_buf_len = strlen(err_str) + strlen(prop_str) + 2;
                    char *tmp_buf = icalmemory_tmp_buffer(tmp_buf_len);
                    snprintf(tmp_buf, tmp_buf_len, "%s %s", err_str, prop_str);

                    insert_error(tail, str, tmp_buf,
                                 ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);

                    value_kind = icalproperty_kind_to_value_kind(prop_kind);

                    icalparameter_free(param);
                    tail = 0;
                    parser->state = ICALPARSER_ERROR;

                    icalmemory_free_buffer(str);
                    str = NULL;
                    pcount++;
                    continue;
                }
            }

            /* Everything is OK, so add the parameter */
            icalproperty_add_parameter(prop, param);
            tail = 0;
            icalmemory_free_buffer(str);
            str = NULL;
            pcount++;

        } else {
            /* str is NULL */
            break;
        }

    }   /* while(1) */

    /**********************************************************************
     * Handle values
     **********************************************************************/

    /* Look for values. If there are ',' characters in the values,
       then there are multiple values, so clone the current
       parameter and add one part of the value to each clone */

    vcount = 0;
    while (vcount < MAXIMUM_ALLOWED_MULTIPLE_VALUES) {
        /* Only some properties can have multiple values. This list was taken
           from rfc5545. Also added the x-properties, because the spec actually
           says that commas should be escaped. For x-properties, other apps may
           depend on that behaviour
         */
        icalmemory_free_buffer(str);
        str = NULL;

        if (icalproperty_value_kind_is_multivalued(prop_kind, &value_kind)) {
            str = parser_get_next_value(end, &end, value_kind);
        } else {
            str = icalparser_get_value(end, &end, value_kind);
        }
        strstriplt(str);

        if (str != 0) {

            if (vcount > 0) {
                /* Actually, only clone after the second value */
                icalproperty *clone = icalproperty_clone(prop);
                icalcomponent *tail = pvl_data(pvl_tail(parser->components));

                icalcomponent_add_property(tail, clone);
                prop = clone;
                tail = 0;
            }

            value = icalvalue_new_from_string(value_kind, str);

            /* Don't add properties without value */
            if (value == 0) {
                char temp[200]; /* HACK */

                icalproperty_kind prop_kind = icalproperty_isa(prop);
                icalcomponent *tail = pvl_data(pvl_tail(parser->components));

                snprintf(temp, sizeof(temp),
                         "Can't parse as %s value in %s property. Removing entire property",
                         icalvalue_kind_to_string(value_kind),
                         icalproperty_kind_to_string(prop_kind));

                insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);

                /* Remove the troublesome property */
                icalcomponent_remove_property(tail, prop);
                icalproperty_free(prop);
                prop = 0;
                tail = 0;
                parser->state = ICALPARSER_ERROR;

                icalmemory_free_buffer(str);
                str = NULL;
                return 0;

            } else {
                vcount++;
                icalproperty_set_value(prop, value);
            }
            icalmemory_free_buffer(str);
            str = NULL;

        } else {
#if ICAL_ALLOW_EMPTY_PROPERTIES
            /* Don't replace empty properties with an error.
               Set an empty length string (not null) as the value instead */
            if (vcount == 0) {
                icalproperty_set_value(prop, icalvalue_new(ICAL_NO_VALUE));
            }

            break;
#else
            if (vcount == 0) {
                char temp[200]; /* HACK */

                icalproperty_kind prop_kind = icalproperty_isa(prop);
                icalcomponent *tail = pvl_data(pvl_tail(parser->components));

                snprintf(temp, sizeof(temp), "No value for %s property. Removing entire property",
                         icalproperty_kind_to_string(prop_kind));

                insert_error(tail, str, temp, ICAL_XLICERRORTYPE_VALUEPARSEERROR);

                /* Remove the troublesome property */
                icalcomponent_remove_property(tail, prop);
                icalproperty_free(prop);
                prop = 0;
                tail = 0;
                parser->state = ICALPARSER_ERROR;
                return 0;
            } else {

                break;
            }
#endif
        }
    }

    /****************************************************************
     * End of component parsing.
     *****************************************************************/

    if (pvl_data(pvl_tail(parser->components)) == 0 && parser->level == 0) {
        /* HACK. Does this clause ever get executed? */
        parser->state = ICALPARSER_SUCCESS;
        assert(0);
        return parser->root_component;
    } else {
        parser->state = ICALPARSER_IN_PROGRESS;
        return 0;
    }
}
Пример #15
0
icalcomponent* icalparser_add_line(icalparser* parser,
                                       char* line)
{ 
    char *str;
    char *end;
    int vcount = 0;
    icalproperty *prop;
    icalproperty_kind prop_kind;
    icalvalue *value;
    icalvalue_kind value_kind = ICAL_NO_VALUE;


    icalerror_check_arg_rz((parser != 0),"parser");


    if (line == 0)
    {
	parser->state = ICALPARSER_ERROR;
	return 0;
    }

    if(line_is_blank(line) == 1){
	return 0;
    }

    /* Begin by getting the property name at the start of the line. The
       property name may end up being "BEGIN" or "END" in which case it
       is not really a property, but the marker for the start or end of
       a component */

    end = 0;
    str = parser_get_prop_name(line, &end);

    if (str == 0 || *str == '\0' ){
	/* Could not get a property name */
	icalcomponent *tail = pvl_data(pvl_tail(parser->components));

	if (tail){
	    insert_error(tail,line,
			 "Got a data line, but could not find a property name or component begin tag",
			 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
	}
	tail = 0;
	parser->state = ICALPARSER_ERROR;
	icalmemory_free_buffer(str);
	str = NULL;
	return 0; 
    }

    /**********************************************************************
     * Handle begin and end of components
     **********************************************************************/
    /* If the property name is BEGIN or END, we are actually
       starting or ending a new component */


    if(strcasecmp(str,"BEGIN") == 0){
	icalcomponent *c;
        icalcomponent_kind comp_kind;

	icalmemory_free_buffer(str);
	str = NULL;

	parser->level++;
	str = parser_get_next_value(end,&end, value_kind);
	    

        comp_kind = icalenum_string_to_component_kind(str);


        if (comp_kind == ICAL_NO_COMPONENT){


	    c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
	    insert_error(c,str,"Parse error in component name",
			 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
        }

	c  =  icalcomponent_new(comp_kind);

	if (c == 0){
	    c = icalcomponent_new(ICAL_XLICINVALID_COMPONENT);
	    insert_error(c,str,"Parse error in component name",
			 ICAL_XLICERRORTYPE_COMPONENTPARSEERROR);
	}
	    
	pvl_push(parser->components,c);

	parser->state = ICALPARSER_BEGIN_COMP;

	icalmemory_free_buffer(str);
	str = NULL;
	return 0;

    } else if (strcasecmp(str,"END") == 0 ) {
	icalcomponent* tail;

	icalmemory_free_buffer(str);
	str = NULL;
	parser->level--;

	str = parser_get_next_value(end,&end, value_kind);

	/* Pop last component off of list and add it to the second-to-last*/
	parser->root_component = pvl_pop(parser->components);

	tail = pvl_data(pvl_tail(parser->components));

	if(tail != 0){
	    icalcomponent_add_component(tail,parser->root_component);
	} 

	tail = 0;
	icalmemory_free_buffer(str);
	str = NULL;

	/* Return the component if we are back to the 0th level */
	if (parser->level == 0){
	    icalcomponent *rtrn; 

	    if(pvl_count(parser->components) != 0){
	    /* There are still components on the stack -- this means
               that one of them did not have a proper "END" */
		pvl_push(parser->components,parser->root_component);
		icalparser_clean(parser); /* may reset parser->root_component*/
	    }

	    assert(pvl_count(parser->components) == 0);

	    parser->state = ICALPARSER_SUCCESS;
	    rtrn = parser->root_component;
	    parser->root_component = 0;
	    return rtrn;

	} else {
	    parser->state = ICALPARSER_END_COMP;
	    return 0;
	}
    }


    /* There is no point in continuing if we have not seen a
       component yet */

    if(pvl_data(pvl_tail(parser->components)) == 0){
	parser->state = ICALPARSER_ERROR;
	icalmemory_free_buffer(str);
	str = NULL;
	return 0;
    }


    /**********************************************************************
     * Handle property names
     **********************************************************************/
								       
    /* At this point, the property name really is a property name,
       (Not a component name) so make a new property and add it to
       the component */

    
    prop_kind = icalproperty_string_to_kind(str);

    prop = icalproperty_new(prop_kind);

    if (prop != 0){
	icalcomponent *tail = pvl_data(pvl_tail(parser->components));

        if(prop_kind==ICAL_X_PROPERTY){
            icalproperty_set_x_name(prop,str);
        }

	icalcomponent_add_property(tail, prop);

	/* Set the value kind for the default for this type of
	   property. This may be re-set by a VALUE parameter */
	value_kind = icalproperty_kind_to_value_kind(icalproperty_isa(prop));

    } else {
	icalcomponent* tail = pvl_data(pvl_tail(parser->components));

	insert_error(tail,str,"Parse error in property name",
		     ICAL_XLICERRORTYPE_PROPERTYPARSEERROR);
	    
	tail = 0;
	parser->state = ICALPARSER_ERROR;
	icalmemory_free_buffer(str);
	str = NULL;
	return 0;
    }

    icalmemory_free_buffer(str);
    str = NULL;

    /**********************************************************************
     * Handle parameter values
     **********************************************************************/								       

    /* Now, add any parameters to the last property */

    while(1) {

	if (*(end-1) == ':'){
	    /* if the last separator was a ":" and the value is a
	       URL, icalparser_get_next_parameter will find the
	       ':' in the URL, so better break now. */
	    break;
	}

	str = parser_get_next_parameter(end,&end);
	strstriplt(str);
	if (str != 0){
	    char* name = 0;
	    char* pvalue = 0;
	    char *buf_value = NULL;
        
	    icalparameter *param = 0;
	    icalparameter_kind kind;
	    icalcomponent *tail = pvl_data(pvl_tail(parser->components));

	    name = parser_get_param_name(str,&pvalue,&buf_value);

	    if (name == 0){
		/* 'tail' defined above */
		insert_error(tail, str, "Cant parse parameter name",
			     ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
		tail = 0;
		break;
	    }

	    kind = icalparameter_string_to_kind(name);

	    if(kind == ICAL_X_PARAMETER){
		param = icalparameter_new(ICAL_X_PARAMETER);
		
		if(param != 0){
		    icalparameter_set_xname(param,name);
		    icalparameter_set_xvalue(param,pvalue);
		}
		icalmemory_free_buffer(buf_value);
		buf_value = NULL;

	    } else if (kind != ICAL_NO_PARAMETER){
		param = icalparameter_new_from_value_string(kind,pvalue);

		icalmemory_free_buffer(buf_value);
		buf_value = NULL;

	    } else {
		/* Error. Failed to parse the parameter*/
		/* 'tail' defined above */

                /* Change for mozilla */
                /* have the option of being flexible towards unsupported parameters */
                #ifndef ICAL_ERRORS_ARE_FATAL
                continue;
                #endif

		insert_error(tail, str, "Cant parse parameter name",
			     ICAL_XLICERRORTYPE_PARAMETERNAMEPARSEERROR);
		tail = 0;
		parser->state = ICALPARSER_ERROR;
		/* if (pvalue) {
			free(pvalue);
			pvalue = 0;
		} */
		if (name) {
			free(name);
			name = 0;
		}
		return 0;
	    }

	    /* if (pvalue) {
		free(pvalue);
		pvalue = 0;
	    } */
	    if (name) {
		free(name);
		name = 0;
	    }

	    if (param == 0){
		/* 'tail' defined above */
		insert_error(tail,str,"Cant parse parameter value",
			     ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
		    
		tail = 0;
		parser->state = ICALPARSER_ERROR;
		
		icalmemory_free_buffer(buf_value);
		buf_value = NULL;
		icalmemory_free_buffer(name);
		name = NULL;
		icalmemory_free_buffer(str);
		str = NULL;
  	  	
		continue;
	    }

	    /* If it is a VALUE parameter, set the kind of value*/
	    if (icalparameter_isa(param)==ICAL_VALUE_PARAMETER){

		value_kind = (icalvalue_kind)
                    icalparameter_value_to_value_kind(
                                icalparameter_get_value(param)
                                );

		if (value_kind == ICAL_NO_VALUE){

		    /* Ooops, could not parse the value of the
		       parameter ( it was not one of the defined
		       values ), so reset the value_kind */
			
		    insert_error(
			tail, str, 
			"Got a VALUE parameter with an unknown type",
			ICAL_XLICERRORTYPE_PARAMETERVALUEPARSEERROR);
		    icalparameter_free(param);
			
		    value_kind = 
			icalproperty_kind_to_value_kind(
			    icalproperty_isa(prop));
			
		    icalparameter_free(param);
		    tail = 0;
		    parser->state = ICALPARSER_ERROR;

			icalmemory_free_buffer(name);
			name = NULL;
			icalmemory_free_buffer(str);
			str = NULL;
		    continue;
		} 
	    }
		icalmemory_free_buffer(name);
		name = NULL;

	    /* Everything is OK, so add the parameter */
	    icalproperty_add_parameter(prop,param);
	    tail = 0;
	    icalmemory_free_buffer(str);
	    str = NULL;

	} else { /* if ( str != 0)  */
	    /* If we did not get a param string, go on to looking for a value */
		if (str != NULL) {
			icalmemory_free_buffer(str);
			str = NULL;
		}
	    break;
	} /* if ( str != 0)  */

    } /* while(1) */	    
	
    /**********************************************************************
     * Handle values
     **********************************************************************/								       

    /* Look for values. If there are ',' characters in the values,
       then there are multiple values, so clone the current
       parameter and add one part of the value to each clone */

    vcount=0;
    while(1) {
        /* Only some properies can have multiple values. This list was taken
           from rfc2445. Also added the x-properties, because the spec actually
           says that commas should be escaped. For x-properties, other apps may
           depend on that behaviour
        */
        switch (prop_kind) {
            case ICAL_X_PROPERTY:
            case ICAL_CATEGORIES_PROPERTY:
            case ICAL_RESOURCES_PROPERTY:
            /* Referring to RFC 2445, section 4.8.5.3 and section 4.8.5.1:
               RDATE and EXDATE can specify a list of dates/date-times/periods.
            */
            case ICAL_RDATE_PROPERTY:
            case ICAL_EXDATE_PROPERTY:
            /* Referring to RFC 2445, section 4.8.2.6 Free/Busy Time:
               The "FREEBUSY" property can specify more than one value, separated by
               the COMMA character (US-ASCII decimal 44).
            */
            case ICAL_FREEBUSY_PROPERTY:
                 str = parser_get_next_value(end,&end, value_kind);
		 strstriplt (str);
                 break;
            default:
                 str = icalparser_get_value(end, &end, value_kind);
		 strstriplt (str);
                 break;
        }

	if (str != 0){
		
	    if (vcount > 0){
		/* Actually, only clone after the second value */
		icalproperty* clone = icalproperty_new_clone(prop);
		icalcomponent* tail = pvl_data(pvl_tail(parser->components));
		    
		icalcomponent_add_property(tail, clone);
		prop = clone;		    
		tail = 0;
	    }
		
	    value = icalvalue_new_from_string(value_kind, str);
		
	    /* Don't add properties without value */
	    if (value == 0){
		char temp[200]; /* HACK */

		icalproperty_kind prop_kind = icalproperty_isa(prop);
		icalcomponent* tail = pvl_data(pvl_tail(parser->components));

		snprintf(temp,sizeof(temp),"Can't parse as %s value in %s property. Removing entire property",
			icalvalue_kind_to_string(value_kind),
			icalproperty_kind_to_string(prop_kind));

		insert_error(tail, str, temp,
			     ICAL_XLICERRORTYPE_VALUEPARSEERROR);

		/* Remove the troublesome property */
		icalcomponent_remove_property(tail,prop);
		icalproperty_free(prop);
		prop = 0;
		tail = 0;
		parser->state = ICALPARSER_ERROR;
	
		icalmemory_free_buffer(str);
		str = NULL;
		return 0;
		    
	    } else {
		vcount++;
		icalproperty_set_value(prop, value);
	    }
 	    icalmemory_free_buffer(str);
	    str = NULL;

	} else {
		if (str != NULL) {
			icalmemory_free_buffer(str);
			str = NULL;
		}
			
	    if (vcount == 0){
		char temp[200]; /* HACK */
		
		icalproperty_kind prop_kind = icalproperty_isa(prop);
		icalcomponent *tail = pvl_data(pvl_tail(parser->components));
		
		snprintf(temp,sizeof(temp),"No value for %s property. Removing entire property",
			icalproperty_kind_to_string(prop_kind));

		insert_error(tail, str, temp,
			     ICAL_XLICERRORTYPE_VALUEPARSEERROR);

		/* Remove the troublesome property */
		icalcomponent_remove_property(tail,prop);
		icalproperty_free(prop);
		prop = 0;
		tail = 0;
		parser->state = ICALPARSER_ERROR;
		return 0;
	    } else {

		break;
	    }
	}
    }
	
    /****************************************************************
     * End of component parsing. 
     *****************************************************************/

    if (pvl_data(pvl_tail(parser->components)) == 0 &&
	parser->level == 0){
	/* HACK. Does this clause ever get executed? */
	parser->state = ICALPARSER_SUCCESS;
	assert(0);
	return parser->root_component;
    } else {
	parser->state = ICALPARSER_IN_PROGRESS;
	return 0;
    }

}
Пример #16
0
/**
 * Get common fields from ECalComponentWithTZ and set them in I_common
 */
void
conv_common_e_to_i (const ECalComponentWithTZ *ectz, I_common *i_common)
{
	GSList *descr_list = NULL;
	const gchar *uid = NULL;
	const gchar *categories = NULL;
	struct icaltimetype *lastModifiedDate;
	struct icaltimetype *createdDate;
	icalcomponent *icomp = NULL;
	icalproperty *prop = NULL;

	i_common->vtimezone = get_vtimezone(ectz);
	sensitivity_e_to_i(ectz->maincomp, i_common);
	link_attachments_e_to_i(ectz->maincomp, i_common);

	/* handle description/body */
	e_cal_component_get_description_list ((ECalComponent*) ectz->maincomp, &descr_list);

	if (descr_list != NULL) {
		ECalComponentText *text = (ECalComponentText*) descr_list->data;
		i_common->body = g_string_new (text->value);
		e_cal_component_free_text_list(descr_list);
	}

	/* ******************************************SET UID************************************ */
	e_cal_component_get_uid (ectz->maincomp, &uid);

	if (uid)
		i_common->uid = g_string_new (uid);

	/* ******************************************SET CATEGORIES************************************ */
	e_cal_component_get_categories (ectz->maincomp, &categories);

	if (categories)
		i_common->categories = g_string_new (categories);

	/* ******************************************SET DATES (CREATION, LASTMODIFICATION, START, END etc.)************************************ */

	e_cal_component_get_last_modified (ectz->maincomp, &lastModifiedDate);
	i_common->last_modified_datetime = new_date_or_datetime();

	if (lastModifiedDate)
		/* log_debug("ICalDate %d-%d-%d-%d-%d-%d", lastModifiedDate->year, lastModifiedDate->month, lastModifiedDate->day, lastModifiedDate->hour, lastModifiedDate->minute, lastModifiedDate->second); */
		date_or_datetime_e_to_i (lastModifiedDate, i_common->last_modified_datetime);
	else {
		/* Set lastModifiedDate to current system time */
		i_common->last_modified_datetime->date_time = g_new0(time_t, 1);
		*(i_common->last_modified_datetime->date_time) = time(NULL);
	}
	g_free(lastModifiedDate);

	i_common->creation_datetime = new_date_or_datetime();
	e_cal_component_get_created (ectz->maincomp, &createdDate);

	if (createdDate)
		date_or_datetime_e_to_i (createdDate, i_common->creation_datetime);
	else {
		/* Set createdDate to current system time */
		i_common->creation_datetime->date_time = g_new0(time_t, 1);
		*(i_common->creation_datetime->date_time) = time(NULL);
	}
	g_free(createdDate);


	/* ******************************************SET ATTACHMENT LIST******************************************************************************* */

	/* iterate over all ical properties */
	icomp = e_cal_component_get_icalcomponent (ectz->maincomp);
	prop = icalcomponent_get_first_property(icomp, ICAL_ANY_PROPERTY);
	while (prop != NULL) {
		icalproperty_kind kind = icalproperty_isa(prop);
		gchar *pname = (gchar*) icalproperty_get_x_name(prop);
		if (ICAL_ATTACH_PROPERTY == kind) /* found kolab inline or link attachment */
			add_e_attachment_parameters(prop, i_common, TRUE);
		else if (pname && strcmp(pname, ICONTACT_KOLAB_STORE_ATTACHMENT) == 0) /* found hidden kolab attachment */
			add_e_attachment_parameters(prop, i_common, FALSE);
		prop = icalcomponent_get_next_property(icomp, ICAL_ANY_PROPERTY);
	}

	i_common->is_html_richtext = FALSE;
}
Пример #17
0
/** Gets the TZNAMEs used for the last STANDARD & DAYLIGHT components
   in a VTIMEZONE. If both STANDARD and DAYLIGHT components use the
   same TZNAME, it returns that. If they use different TZNAMEs, it
   formats them like "EST/EDT". The returned string should be freed by
   the caller. */
static char*
icaltimezone_get_tznames_from_vtimezone (icalcomponent *component)
{
    icalcomponent *comp;
    icalcomponent_kind type;
    icalproperty *prop;
    struct icaltimetype dtstart;
    struct icaldatetimeperiodtype rdate;
    const char *current_tzname;
    const char *standard_tzname = NULL, *daylight_tzname = NULL;
    struct icaltimetype standard_max_date, daylight_max_date;
    struct icaltimetype current_max_date;

    standard_max_date = icaltime_null_time();
    daylight_max_date = icaltime_null_time();

    /* Step through the STANDARD & DAYLIGHT subcomponents. */
    comp = icalcomponent_get_first_component (component, ICAL_ANY_COMPONENT);
    while (comp) {
	type = icalcomponent_isa (comp);
	if (type == ICAL_XSTANDARD_COMPONENT
	    || type == ICAL_XDAYLIGHT_COMPONENT) {
	    current_max_date = icaltime_null_time ();
	    current_tzname = NULL;

	    /* Step through the properties. We want to find the TZNAME, and
	       the largest DTSTART or RDATE. */
	    prop = icalcomponent_get_first_property (comp, ICAL_ANY_PROPERTY);
	    while (prop) {
		switch (icalproperty_isa (prop)) {
		case ICAL_TZNAME_PROPERTY:
		    current_tzname = icalproperty_get_tzname (prop);
		    break;

		case ICAL_DTSTART_PROPERTY:
		    dtstart = icalproperty_get_dtstart (prop);
		    if (icaltime_compare (dtstart, current_max_date) > 0)
			current_max_date = dtstart;

		    break;

		case ICAL_RDATE_PROPERTY:
		    rdate = icalproperty_get_rdate (prop);
		    if (icaltime_compare (rdate.time, current_max_date) > 0)
			current_max_date = rdate.time;

		    break;

		default:
		    break;
		}

		prop = icalcomponent_get_next_property (comp,
							ICAL_ANY_PROPERTY);
	    }

	    if (current_tzname) {
		if (type == ICAL_XSTANDARD_COMPONENT) {
		    if (!standard_tzname
			|| icaltime_compare (current_max_date,
					     standard_max_date) > 0) {
			standard_max_date = current_max_date;
			standard_tzname = current_tzname;
		    }
		} else {
		    if (!daylight_tzname
			|| icaltime_compare (current_max_date,
					     daylight_max_date) > 0) {
			daylight_max_date = current_max_date;
			daylight_tzname = current_tzname;
		    }
		}
	    }
	}

        comp = icalcomponent_get_next_component (component,
						 ICAL_ANY_COMPONENT);
    }

    /* Outlook (2000) places "Standard Time" and "Daylight Time" in the TZNAME
       strings, which is totally useless. So we return NULL in that case. */
    if (standard_tzname && !strcmp (standard_tzname, "Standard Time"))
	return NULL;

    /* If both standard and daylight TZNAMEs were found, if they are the same
       we return just one, else we format them like "EST/EDT". */
    if (standard_tzname && daylight_tzname) {
	unsigned int standard_len, daylight_len;
	char *tznames;

	if (!strcmp (standard_tzname, daylight_tzname))
	    return strdup (standard_tzname);

	standard_len = strlen (standard_tzname);
	daylight_len = strlen (daylight_tzname);
	tznames = malloc (standard_len + daylight_len + 2);
	strcpy (tznames, standard_tzname);
	tznames[standard_len] = '/';
	strcpy (tznames + standard_len + 1, daylight_tzname);
	return tznames;
    } else {
	const char *tznames;

	/* If either of the TZNAMEs was found just return that, else NULL. */
	tznames = standard_tzname ? standard_tzname : daylight_tzname;
	return tznames ? strdup (tznames) : NULL;
    }
}