icalerrorenum icalcluster_remove_component(icalcluster *impl, icalcomponent* child) { icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); icalerror_check_arg_re((child!=0),"child",ICAL_BADARG_ERROR); icalcomponent_remove_component(impl->data,child); icalcluster_mark(impl); return ICAL_NO_ERROR; }
icalerrorenum icalbdbset_select(icalset *set, icalgauge *gauge) { icalbdbset *bset = (icalbdbset *) set; icalerror_check_arg_re((bset != 0), "bset", ICAL_BADARG_ERROR); icalerror_check_arg_re(gauge != 0, "gauge", ICAL_BADARG_ERROR); bset->gauge = gauge; return ICAL_NO_ERROR; }
icalerrorenum icaldirset_select(icalset *set, icalgauge *gauge) { icaldirset *dset; icalerror_check_arg_re((set != 0), "set", ICAL_BADARG_ERROR); icalerror_check_arg_re((gauge != 0), "gauge", ICAL_BADARG_ERROR); dset = (icaldirset *) set; dset->gauge = gauge; return ICAL_NO_ERROR; }
icalerrorenum icaldirset_remove_component(icalset *set, icalcomponent *comp) { icaldirset *dset; icalcomponent *filecomp; icalcompiter i; int found = 0; icalerror_check_arg_re((set != 0), "set", ICAL_BADARG_ERROR); icalerror_check_arg_re((comp != 0), "comp", ICAL_BADARG_ERROR); dset = (icaldirset *) set; icalerror_check_arg_re((dset->cluster != 0), "Cluster pointer", ICAL_USAGE_ERROR); filecomp = icalcluster_get_component(dset->cluster); for (i = icalcomponent_begin_component(filecomp, ICAL_ANY_COMPONENT); icalcompiter_deref(&i) != 0; icalcompiter_next(&i)) { icalcomponent *this = icalcompiter_deref(&i); if (this == comp) { found = 1; break; } } if (found != 1) { icalerror_warn("icaldirset_remove_component: component is not part of current cluster"); icalerror_set_errno(ICAL_USAGE_ERROR); return ICAL_USAGE_ERROR; } (void)icalcluster_remove_component(dset->cluster, comp); /* icalcluster_mark(impl->cluster); */ /* If the removal emptied the fileset, get the next fileset */ if (icalcluster_count_components(dset->cluster, ICAL_ANY_COMPONENT) == 0) { icalerrorenum error = icaldirset_next_cluster(dset); if (dset->cluster != 0 && error == ICAL_NO_ERROR) { (void)icalcluster_get_first_component(dset->cluster); } else { /* HACK. Not strictly correct for impl->cluster==0 */ return error; } } else { /* Do nothing */ } return ICAL_NO_ERROR; }
icalerrorenum icalbdbset_remove_component(icalset *set, icalcomponent *child) { icalbdbset *bset = (icalbdbset *) set; icalerror_check_arg_re((bset != 0), "bset", ICAL_BADARG_ERROR); icalerror_check_arg_re((child != 0), "child", ICAL_BADARG_ERROR); icalcomponent_remove_component(bset->cluster, child); icalbdbset_mark(set); return ICAL_NO_ERROR; }
static icalerrorenum icalcalendar_create(struct icalcalendar_impl *impl) { char path[MAXPATHLEN]; struct stat sbuf; int r; icalerror_check_arg_re((impl != 0), "impl", ICAL_BADARG_ERROR); path[0] = '\0'; strncpy(path, impl->dir, MAXPATHLEN - 1); strncat(path, "/", MAXPATHLEN - strlen(path) - 1); strncat(path, BOOKED_DIR, MAXPATHLEN - strlen(path) - 1); path[MAXPATHLEN - 1] = '\0'; r = stat(path, &sbuf); if (r != 0 && errno == ENOENT) { if (mkdir(path, 0777) != 0) { icalerror_set_errno(ICAL_FILE_ERROR); return ICAL_FILE_ERROR; } } return ICAL_NO_ERROR; }
int icalcluster_count_components(icalcluster *impl, icalcomponent_kind kind) { icalerror_check_arg_re((impl!=0),"cluster",ICAL_BADARG_ERROR); return icalcomponent_count_components(impl->data, kind); }
icalerrorenum icalbdbset_commit(icalset *set) { DB *dbp; DBC *dbcp; DBT key, data; icalcomponent *c; char *str = NULL; int ret = 0; int reterr = ICAL_NO_ERROR; char keystore[256]; char uidbuf[256]; char datastore[1024]; char *more_mem = NULL; DB_TXN *tid = NULL; icalbdbset *bset = (icalbdbset *) set; int bad_uid_counter = 0; int retry = 0, done = 0, completed = 0, deadlocked = 0; icalerror_check_arg_re((bset != 0), "bset", ICAL_BADARG_ERROR); dbp = bset->dbp; icalerror_check_arg_re((dbp != 0), "dbp is invalid", ICAL_BADARG_ERROR); if (bset->changed == 0) { return ICAL_NO_ERROR; } memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); key.flags = DB_DBT_USERMEM; key.data = keystore; key.ulen = (u_int32_t) sizeof(keystore); data.flags = DB_DBT_USERMEM; data.data = datastore; data.ulen = (u_int32_t) sizeof(datastore); if (!ICAL_DB_ENV) { if (icalbdbset_init_dbenv(NULL, NULL) != 0) { return ICAL_INTERNAL_ERROR; } } while ((retry < MAX_RETRY) && !done) { if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) { if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit: txn_begin failed"); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "icalbdbset_commit"); return ICAL_INTERNAL_ERROR; } } /* first delete everything in the database, because there could be removed components */ if ((ret = dbp->cursor(dbp, tid, &dbcp, DB_DIRTY_READ)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed"); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "curor failed"); /* leave bset->changed set to true */ return ICAL_INTERNAL_ERROR; } } /* fetch the key/data pair, then delete it */ completed = 0; while (!completed && !deadlocked) { ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT); if (ret == DB_NOTFOUND) { completed = 1; } else if (ret == ENOMEM) { if (more_mem) { free(more_mem); } more_mem = malloc(data.ulen + 1024); data.data = more_mem; data.ulen = data.ulen + 1024; } else if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else if (ret == DB_RUNRECOVERY) { tid->abort(tid); ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_get failed."); abort(); } else if (ret == 0) { if ((ret = dbcp->c_del(dbcp, 0)) != 0) { dbp->err(dbp, ret, "cursor"); if (ret == DB_KEYEMPTY) { /* never actually created, continue onward.. */ /* do nothing - break; */ } else if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else { /*char *foo = db_strerror(ret); */ abort(); } } } else { /* some other non-fatal error */ dbcp->c_close(dbcp); tid->abort(tid); if (more_mem) { free(more_mem); more_mem = NULL; } return ICAL_INTERNAL_ERROR; } } if (more_mem) { free(more_mem); more_mem = NULL; } if (deadlocked) { dbcp->c_close(dbcp); tid->abort(tid); retry++; continue; /* next retry */ } deadlocked = 0; for (c = icalcomponent_get_first_component(bset->cluster, ICAL_ANY_COMPONENT); c != 0 && !deadlocked; c = icalcomponent_get_next_component(bset->cluster, ICAL_ANY_COMPONENT)) { memset(&key, 0, sizeof(key)); memset(&data, 0, sizeof(data)); /* Note that we're always inserting into a primary index. */ if (icalcomponent_isa(c) != ICAL_VAGENDA_COMPONENT) { char *uidstr = (char *)icalcomponent_get_uid(c); if (!uidstr) { /* this shouldn't happen */ /* no uid string, we need to add one */ snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++); key.data = uidbuf; } else { key.data = uidstr; } } else { char *relcalid = NULL; relcalid = (char *)icalcomponent_get_relcalid(c); if (relcalid == NULL) { snprintf(uidbuf, 256, "baduid%d-%d", getpid(), bad_uid_counter++); key.data = uidbuf; } else { key.data = relcalid; } } key.size = (u_int32_t) strlen(key.data); str = icalcomponent_as_ical_string_r(c); data.data = str; data.size = (u_int32_t) strlen(str); if ((ret = dbcp->c_put(dbcp, &key, &data, DB_KEYLAST)) != 0) { if (ret == DB_LOCK_DEADLOCK) { deadlocked = 1; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_put failed %s.", str); /* continue to try to put as many icalcomponent as possible */ reterr = ICAL_INTERNAL_ERROR; } } } if (str) { free(str); } if (deadlocked) { dbcp->c_close(dbcp); tid->abort(tid); retry++; continue; } if ((ret = dbcp->c_close(dbcp)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "c_closed failed."); reterr = ICAL_INTERNAL_ERROR; } } if ((ret = tid->commit(tid, 0)) != 0) { tid->abort(tid); if (ret == DB_LOCK_DEADLOCK) { retry++; continue; } else if (ret == DB_RUNRECOVERY) { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed."); abort(); } else { ICAL_DB_ENV->err(ICAL_DB_ENV, ret, "commit failed."); reterr = ICAL_INTERNAL_ERROR; } } done = 1; } bset->changed = 0; return reterr; }
icalsetiter icalbdbset_begin_component(icalset *set, icalcomponent_kind kind, icalgauge *gauge, const char *tzid) { icalsetiter itr = icalsetiter_null; icalcomponent *comp = NULL; icalcompiter citr; icalbdbset *bset; struct icaltimetype start, next; icalproperty *dtstart, *rrule, *prop, *due; struct icalrecurrencetype recur; icaltimezone *u_zone; int g = 0; int orig_time_was_utc = 0; icalerror_check_arg_re((set != 0), "set", icalsetiter_null); bset = (icalbdbset *) set; itr.gauge = gauge; itr.tzid = tzid; citr = icalcomponent_begin_component(bset->cluster, kind); comp = icalcompiter_deref(&citr); if (gauge == 0) { itr.iter = citr; return itr; } /* if there is a gauge, the first matched component is returned */ while (comp != 0) { /* check if it is a recurring component and with guage expand, if so * we need to add recurrence-id property to the given component */ rrule = icalcomponent_get_first_property(comp, ICAL_RRULE_PROPERTY); g = icalgauge_get_expand(gauge); if (rrule != 0 && g == 1) { /* it is a recurring event */ u_zone = icaltimezone_get_builtin_timezone(itr.tzid); /* use UTC, if that's all we have. */ if (!u_zone) { u_zone = icaltimezone_get_utc_timezone(); } recur = icalproperty_get_rrule(rrule); start = icaltime_from_timet(time(0), 0); if (icalcomponent_isa(comp) == ICAL_VEVENT_COMPONENT) { dtstart = icalcomponent_get_first_property(comp, ICAL_DTSTART_PROPERTY); if (dtstart) { start = icalproperty_get_dtstart(dtstart); } } else if (icalcomponent_isa(comp) == ICAL_VTODO_COMPONENT) { due = icalcomponent_get_first_property(comp, ICAL_DUE_PROPERTY); if (due) { start = icalproperty_get_due(due); } } /* Convert to the user's timezone in order to be able to compare * the results from the rrule iterator. */ if (icaltime_is_utc(start)) { start = icaltime_convert_to_zone(start, u_zone); orig_time_was_utc = 1; } if (itr.last_component == NULL) { itr.ritr = icalrecur_iterator_new(recur, start); next = icalrecur_iterator_next(itr.ritr); itr.last_component = comp; } else { next = icalrecur_iterator_next(itr.ritr); if (icaltime_is_null_time(next)) { itr.last_component = NULL; icalrecur_iterator_free(itr.ritr); itr.ritr = NULL; /* no matched occurrence */ goto getNextComp; } else { itr.last_component = comp; } } /* if it is excluded, do next one */ if (icalproperty_recurrence_is_excluded(comp, &start, &next)) { next = icalrecur_iterator_next(itr.ritr); continue; } /* add recurrence-id value to the property if the property already exist; * add the recurrence id property and the value if the property does not exist */ prop = icalcomponent_get_first_property(comp, ICAL_RECURRENCEID_PROPERTY); if (prop == 0) { icalcomponent_add_property(comp, icalproperty_new_recurrenceid(next)); } else { icalproperty_set_recurrenceid(prop, next); } /* convert the next recurrence time into the user's timezone */ if (orig_time_was_utc) { next = icaltime_convert_to_zone(next, icaltimezone_get_utc_timezone()); } } /* end of a recurring event */ if (gauge == 0 || icalgauge_compare(itr.gauge, comp) == 1) { /* find a matched and return it */ itr.iter = citr; return itr; } /* if it is a recurring but no matched occurrence has been found OR * it is not a recurring and no matched component has been found, * read the next component to find out */ getNextComp: if ((rrule != NULL && itr.last_component == NULL) || (rrule == NULL)) { (void)icalcompiter_next(&citr); comp = icalcompiter_deref(&citr); } } /* while */ /* no matched component has found */ return icalsetiter_null; }
/** @brief Contructor. * * Create a time from an ISO format string. * * @todo If the given string specifies a DATE-TIME not in UTC, there * is no way to know if this is a floating time or really refers to a * timezone. We should probably add a new constructor: * icaltime_from_string_with_zone() */ struct icaltimetype icaltime_from_string(const char *str) { struct icaltimetype tt = icaltime_null_time(); size_t size; icalerror_check_arg_re(str != 0, "str", icaltime_null_time()); size = strlen(str); if ((size == 15) || (size == 19)) { /* floating time with/without separators */ tt.is_utc = 0; tt.is_date = 0; } else if ((size == 16) || (size == 20)) { /* UTC time, ends in 'Z' */ if ((str[15] != 'Z') && (str[19] != 'Z')) goto FAIL; tt.is_utc = 1; tt.zone = icaltimezone_get_utc_timezone(); tt.is_date = 0; } else if ((size == 8) || (size == 10)) { /* A DATE */ tt.is_utc = 0; tt.is_date = 1; } else { /* error */ goto FAIL; } if (tt.is_date == 1) { if (size == 10) { char dsep1, dsep2; if (sscanf(str, "%04d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day) < 5) { goto FAIL; } if ((dsep1 != '-') || (dsep2 != '-')) { goto FAIL; } } else if (sscanf(str, "%04d%02d%02d", &tt.year, &tt.month, &tt.day) < 3) { goto FAIL; } } else { if (size > 16) { char dsep1, dsep2, tsep, tsep1, tsep2; if (sscanf(str, "%04d%c%02d%c%02d%c%02d%c%02d%c%02d", &tt.year, &dsep1, &tt.month, &dsep2, &tt.day, &tsep, &tt.hour, &tsep1, &tt.minute, &tsep2, &tt.second) < 11) { goto FAIL; } if ((tsep != 'T') || (dsep1 != '-') || (dsep2 != '-') || (tsep1 != ':') || (tsep2 != ':')) { goto FAIL; } } else { char tsep; if (sscanf(str, "%04d%02d%02d%c%02d%02d%02d", &tt.year, &tt.month, &tt.day, &tsep, &tt.hour, &tt.minute, &tt.second) < 7) { goto FAIL; } if (tsep != 'T') { goto FAIL; } } } return tt; FAIL: icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); return icaltime_null_time(); }
struct icalrecurrencetype icalrecurrencetype_from_string(const char* str) { struct icalrecur_parser parser; memset(&parser,0,sizeof(parser)); icalrecurrencetype_clear(&parser.rt); icalerror_check_arg_re(str!=0,"str",parser.rt); /* Set up the parser struct */ parser.rule = str; parser.copy = _strdup(parser.rule); parser.this_clause = parser.copy; if(parser.copy == 0){ //icalerror_set_errno(ICAL_NEWFAILED_ERROR); return parser.rt; } /* Loop through all of the clauses */ for(icalrecur_first_clause(&parser); parser.this_clause != 0; icalrecur_next_clause(&parser)) { char *name, *value; icalrecur_clause_name_and_value(&parser,&name,&value); if(name == 0){ icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); free(parser.copy); return parser.rt; } if (strcasecmp(name,"FREQ") == 0){ parser.rt.freq = icalrecur_string_to_freq(value); } else if (strcasecmp(name,"COUNT") == 0){ int v = atoi(value); if (v >= 0) { parser.rt.count = v; } } else if (strcasecmp(name,"UNTIL") == 0){ parser.rt.until = icaltime_from_string(value); } else if (strcasecmp(name,"INTERVAL") == 0){ int v = atoi(value); if (v > 0 && v <= SHRT_MAX) { parser.rt.interval = (short) v; } } else if (strcasecmp(name,"WKST") == 0){ parser.rt.week_start = icalrecur_string_to_weekday(value); sort_bydayrules(parser.rt.by_day, parser.rt.week_start); } else if (strcasecmp(name,"BYSECOND") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_second, ICAL_BY_SECOND_SIZE,value); } else if (strcasecmp(name,"BYMINUTE") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_minute, ICAL_BY_MINUTE_SIZE,value); } else if (strcasecmp(name,"BYHOUR") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_hour, ICAL_BY_HOUR_SIZE,value); } else if (strcasecmp(name,"BYDAY") == 0){ icalrecur_add_bydayrules(&parser,value); } else if (strcasecmp(name,"BYMONTHDAY") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_month_day, ICAL_BY_MONTHDAY_SIZE,value); } else if (strcasecmp(name,"BYYEARDAY") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_year_day, ICAL_BY_YEARDAY_SIZE,value); } else if (strcasecmp(name,"BYWEEKNO") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_week_no, ICAL_BY_WEEKNO_SIZE,value); } else if (strcasecmp(name,"BYMONTH") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_month, ICAL_BY_MONTH_SIZE,value); } else if (strcasecmp(name,"BYSETPOS") == 0){ icalrecur_add_byrules(&parser,parser.rt.by_set_pos, ICAL_BY_SETPOS_SIZE,value); } else { icalerror_set_errno(ICAL_MALFORMEDDATA_ERROR); icalrecurrencetype_clear(&parser.rt); free(parser.copy); return parser.rt; } } free(parser.copy); return parser.rt; }