24#include "icalfilesetimpl.h"
25#include "icalerror_p.h"
37#if defined(_WIN32_WCE)
44static int _compare_ids(
const char *compid,
const char *matchid);
60 reader_options.
flags = O_RDONLY;
69 writer_options.
flags = O_RDONLY;
80 long cluster_file_size;
83 icalerror_check_arg_rz((path != 0),
"path");
84 icalerror_check_arg_rz((fset != 0),
"fset");
86 fset->path = strdup(path);
87 fset->options = *options;
89 flags = options->
flags;
92 cluster_file_size = icalfileset_filesize(fset);
94 if (cluster_file_size < 0) {
99 fset->fd = open(fset->path, flags, (mode_t)mode);
107 (void)icalfileset_lock(fset);
109 if (cluster_file_size > 0) {
121 if (fset->cluster == 0) {
152static char *icalfileset_read_from_file(
char *s,
size_t size,
void *d)
159 for (p = s; p < s + size - 1; p++) {
160 if (read(set->fd, p, 1) != 1 || *p ==
'\n') {
195 icalcomponent *cl = set->cluster;
208 if (!fset || !fset->path || fset->path[0] ==
'\0') {
212 if (stat(fset->path, &sbuf) != 0) {
215 if (errno == ENOENT) {
226 if (!S_ISREG(sbuf.st_mode)) {
232 return (
long)sbuf.st_size;
241 icalerror_check_arg_rv((set != 0),
"set");
245 if (fset->cluster != 0) {
251 if (fset->gauge != 0) {
257 (void)icalfileset_unlock(fset);
262 if (fset->path != 0) {
270 icalerror_check_arg_rz((set != 0),
"set");
281 icalerror_check_arg_rz((set->fd > 0),
"set->fd");
283 lock.l_type = F_WRLCK;
285 lock.l_whence = SEEK_SET;
288 rtrn = fcntl(set->fd, F_SETLKW, &lock);
302 icalerror_check_arg_rz((set->fd > 0),
"set->fd");
304 lock.l_type = F_WRLCK;
306 lock.l_whence = SEEK_SET;
309 return (fcntl(set->fd, F_UNLCK, &lock));
317static int file_copy(
const char *fileSource,
const char *fileDestination)
320 FILE *stream_R, *stream_W;
322 if ((stream_R = fopen(fileSource,
"r")) == (FILE *)NULL) {
325 if ((stream_W = fopen(fileDestination,
"w")) == (FILE *)NULL) {
330 while (!feof(stream_R) && !ferror(stream_R)) {
331 size_t bytes = fread(c, 1,
sizeof(c), stream_R);
333 (void)fwrite(c, 1, bytes, stream_W);
346 char backupFile[MAXPATHLEN];
350 size_t write_size = 0;
358 if (fset->changed == 0) {
362 if (fset->options.safe_saves == 1) {
363 strncpy(backupFile, fset->path, MAXPATHLEN - 4);
364 strncat(backupFile,
".bak", MAXPATHLEN - 1);
365 if (file_copy(fset->path, backupFile) != 0) {
371 if (lseek(fset->fd, 0, SEEK_SET) < 0) {
382 sz = write(fset->fd,
str, (IO_SIZE_T)strlen(
str));
383 if (sz != (IO_SSIZE_T)strlen(
str)) {
392 write_size += (size_t)sz;
399 if (ftruncate(fset->fd, (off_t)write_size) < 0) {
403#if !defined(_WIN32_WCE)
404 chsize(fset->fd, tell(fset->fd));
406 SetEndOfFile(fset->fd);
415 icalerror_check_arg_rv((set != 0),
"set");
424 icalerror_check_arg_rz((set != 0),
"set");
427 return fset->cluster;
491 icalerror_check_arg_rv(set != 0,
"set");
504 icalerror_check_arg_rz(set != 0,
"set");
510 icalcomponent *inner;
519 icalerror_warn(
"icalfileset_fetch found a component with no UID");
523 if (strcmp(uid, this_uid) == 0) {
543struct icalfileset_id {
549static void icalfileset_id_free(
struct icalfileset_id *
id)
551 if (id->recurrence_id != 0) {
552 free(id->recurrence_id);
560static struct icalfileset_id icalfileset_get_id(const icalcomponent *comp)
562 icalcomponent *inner;
563 struct icalfileset_id id;
585 id.recurrence_id = NULL;
592 assert(
id.recurrence_id != 0);
602static int _compare_ids(
const char *compid,
const char *matchid)
604 if (compid != NULL && matchid != NULL) {
605 if (strcmp(compid, matchid) == 0) {
610 if (compid == NULL && matchid == NULL) {
622 struct icalfileset_id comp_id, match_id;
624 comp_id = icalfileset_get_id(comp);
630 match_id = icalfileset_get_id(match);
632 if (_compare_ids(comp_id.uid, match_id.uid) &&
633 _compare_ids(comp_id.recurrence_id, match_id.recurrence_id)) {
636 icalfileset_id_free(&match_id);
637 icalfileset_id_free(&comp_id);
641 icalfileset_id_free(&match_id);
644 icalfileset_id_free(&comp_id);
662 icalerror_check_arg_rz((set != 0),
"set");
670 icalcomponent *c = 0;
673 icalerror_check_arg_rz((set != 0),
"set");
697 icalerror_check_arg_rz((set != 0),
"set");
745 icalcomponent *comp = NULL;
773 if (recur != 0 && g == 1) {
828 icalcomponent *comp = NULL;
830 icalproperty *rrule, *prop;
836 if (comp == NULL || itr->
gauge == NULL) {
859 if (itr->
ritr == NULL) {
894 icalcomponent *c = NULL;
896 icalproperty *dtstart, *rrule, *prop, *due;
920 if (recur != 0 && g == 1) {
933 if (i->
ritr == NULL) {
icalcomponent * icalcluster_get_component(const icalcluster *cluster)
icalcluster * icalcluster_new(const char *key, icalcomponent *data)
Create a cluster with a key/value pair.
struct icalcluster_impl icalcluster
icalproperty * icalcomponent_get_first_property(icalcomponent *c, icalproperty_kind kind)
icalcomponent * icalcompiter_next(icalcompiter *i)
icalcomponent * icalcomponent_get_next_component(icalcomponent *c, icalcomponent_kind kind)
icalcomponent * icalcomponent_get_first_component(icalcomponent *c, icalcomponent_kind kind)
icalcomponent * icalcomponent_get_current_component(icalcomponent *component)
void icalcomponent_remove_property(icalcomponent *component, icalproperty *property)
void icalcomponent_remove_component(icalcomponent *parent, icalcomponent *child)
icalcomponent * icalcompiter_deref(icalcompiter *i)
icalcomponent * icalcomponent_new(icalcomponent_kind kind)
icalcomponent * icalcomponent_get_first_real_component(const icalcomponent *c)
icalcomponent * icalcomponent_clone(const icalcomponent *old)
void icalcomponent_add_property(icalcomponent *component, icalproperty *property)
icalcompiter icalcomponent_begin_component(icalcomponent *component, icalcomponent_kind kind)
char * icalcomponent_as_ical_string_r(const icalcomponent *component)
icalcomponent_kind icalcomponent_isa(const icalcomponent *component)
void icalcomponent_free(icalcomponent *c)
void icalcomponent_add_component(icalcomponent *parent, icalcomponent *child)
int icalcomponent_count_components(icalcomponent *component, icalcomponent_kind kind)
const char * icalproperty_get_uid(const icalproperty *prop)
int icalproperty_get_sequence(const icalproperty *prop)
struct icalrecurrencetype * icalproperty_get_rrule(const icalproperty *prop)
struct icaltimetype icalproperty_get_dtstart(const icalproperty *prop)
@ ICAL_RECURRENCEID_PROPERTY
struct icaltimetype icalproperty_get_due(const icalproperty *prop)
icalproperty * icalproperty_new_recurrenceid(struct icaltimetype v)
struct icalvalue_impl icalvalue
enum icalrequeststatus kind
void icalerror_set_errors_are_fatal(bool fatal)
Change if errors are fatal.
bool icalerror_get_errors_are_fatal(void)
Determine if errors are fatal.
void icalerror_set_errno(icalerrorenum x)
Sets the icalerrno to a given error.
void icalerror_clear_errno(void)
Resets icalerrno to ICAL_NO_ERROR.
icalerrorenum
Represents the different types of errors that can be triggered in libical.
#define icalerrno
Access the current icalerrno value.
icalset * icalfileset_new(const char *path)
icalcluster * icalfileset_produce_icalcluster(const char *path)
int icalfileset_has_uid(icalset *set, const char *uid)
icalcomponent * icalfileset_get_current_component(icalset *set)
void icalfileset_mark(icalset *set)
const char * icalfileset_path(icalset *set)
icalerrorenum icalfileset_select(icalset *set, icalgauge *gauge)
icalerrorenum icalfileset_modify(icalset *set, icalcomponent *old, icalcomponent *new)
Modifies components according to the MODIFY method of CAP.
void icalfileset_clear(icalset *set)
Clears the gauge.
icalcomponent * icalfileset_get_component(icalset *set)
icalset * icalfileset_new_reader(const char *path)
icalfileset_options icalfileset_options_default
icalcomponent * icalfileset_get_next_component(icalset *set)
icalerrorenum icalfileset_remove_component(icalset *set, icalcomponent *child)
int icalfileset_count_components(icalset *set, icalcomponent_kind kind)
icalcomponent * icalfileset_form_a_matched_recurrence_component(icalsetiter *itr)
icalcomponent * icalfilesetiter_to_next(icalset *set, icalsetiter *i)
icalerrorenum icalfileset_add_component(icalset *set, icalcomponent *child)
icalcomponent * icalfileset_fetch(icalset *set, icalcomponent_kind kind, const char *uid)
Gets and searches for a component by uid.
icalset * icalfileset_init(icalset *set, const char *path, void *options_in)
icalcomponent * icalfileset_fetch_match(icalset *set, const icalcomponent *comp)
icalerrorenum icalfileset_commit(icalset *set)
void icalfileset_free(icalset *set)
icalsetiter icalfileset_begin_component(icalset *set, icalcomponent_kind kind, icalgauge *gauge, const char *tzid)
icalcomponent * icalfileset_get_first_component(icalset *set)
icalset * icalfileset_new_writer(const char *path)
Manages a database of ical components and offers interfaces for reading, writing and searching for co...
struct icalfileset_impl icalfileset
bool icalgauge_compare(icalgauge *gauge, icalcomponent *comp)
void icalgauge_free(icalgauge *gauge)
int icalgauge_get_expand(const icalgauge *gauge)
void icalmemory_free_buffer(void *buf)
Releases a buffer.
Common memory management routines.
icalcomponent * icalparser_parse(icalparser *parser, icalparser_line_gen_func line_gen_func)
Message oriented parsing.
void icalparser_free(icalparser *parser)
Frees an icalparser object.
icalparser * icalparser_new(void)
Creates a new icalparser.
void icalparser_set_gen_data(icalparser *parser, void *data)
Sets the data that icalparser_parse will give to the line_gen_func as the parameter 'd'.
icalvalue * icalproperty_get_value(const icalproperty *prop)
void icalrecur_iterator_free(icalrecur_iterator *impl)
icalrecur_iterator * icalrecur_iterator_new(struct icalrecurrencetype *rule, struct icaltimetype dtstart)
struct icaltimetype icalrecur_iterator_next(icalrecur_iterator *impl)
icalsetiter icalsetiter_null
icalset * icalset_new(icalset_kind kind, const char *dsn, void *options)
struct icaltimetype icaltime_from_timet_with_zone(const icaltime_t tm, const bool is_date, const icaltimezone *zone)
Constructor.
bool icaltime_is_null_time(const struct icaltimetype t)
char * icalvalue_as_ical_string_r(const icalvalue *value)
Defines the data structure representing iCalendar parameter values.
Options for opening an icalfileset.
icalrecur_iterator * ritr
icalcomponent * last_component