24#include "icalfilesetimpl.h"
25#include "icalerror_p.h"
37#if defined(_WIN32_WCE)
44static int _compare_ids(
const char *compid,
const char *matchid);
46static int icalfileset_lock(icalfileset *set);
47static int icalfileset_unlock(icalfileset *set);
48static icalerrorenum icalfileset_read_file(icalfileset *set,
int mode);
49static long icalfileset_filesize(icalfileset *set);
51icalset *icalfileset_new(
const char *path)
56icalset *icalfileset_new_reader(
const char *path)
60 reader_options.
flags = O_RDONLY;
65icalset *icalfileset_new_writer(
const char *path)
69 writer_options.
flags = O_RDONLY;
74icalset *icalfileset_init(icalset *set,
const char *path,
void *options_in)
77 icalfileset *fset = (icalfileset *)set;
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) {
95 icalfileset_free(set);
99 fset->fd = open(fset->path, flags, (mode_t)mode);
103 icalfileset_free(set);
107 (void)icalfileset_lock(fset);
109 if (cluster_file_size > 0) {
111 icalfileset_free(set);
121 if (fset->cluster == 0) {
128icalcluster *icalfileset_produce_icalcluster(
const char *path)
137 fileset = icalfileset_new_reader(path);
144 icalfileset_free(fileset);
152static char *icalfileset_read_from_file(
char *s,
size_t size,
void *d)
155 icalfileset *set = d;
159 for (p = s; p < s + size - 1; p++) {
160 if (read(set->fd, p, 1) != 1 || *p ==
'\n') {
175icalerrorenum icalfileset_read_file(icalfileset *set,
int mode)
195 icalcomponent *cl = set->cluster;
204long icalfileset_filesize(icalfileset *fset)
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;
237void icalfileset_free(icalset *set)
241 icalerror_check_arg_rv((set != 0),
"set");
243 fset = (icalfileset *)set;
245 if (fset->cluster != 0) {
246 (void)icalfileset_commit(set);
251 if (fset->gauge != 0) {
257 (void)icalfileset_unlock(fset);
262 if (fset->path != 0) {
268const char *icalfileset_path(icalset *set)
270 icalerror_check_arg_rz((set != 0),
"set");
272 return ((icalfileset *)set)->path;
275int icalfileset_lock(icalfileset *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);
297int icalfileset_unlock(icalfileset *set)
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;
352 icalfileset *fset = (icalfileset *)set;
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);
413void icalfileset_mark(icalset *set)
415 icalerror_check_arg_rv((set != 0),
"set");
417 ((icalfileset *)set)->changed = 1;
422 const icalfileset *fset;
424 icalerror_check_arg_rz((set != 0),
"set");
426 fset = (icalfileset *)set;
427 return fset->cluster;
432icalerrorenum icalfileset_add_component(icalset *set, icalcomponent *child)
439 fset = (icalfileset *)set;
442 icalfileset_mark(set);
447icalerrorenum icalfileset_remove_component(icalset *set, icalcomponent *child)
454 fset = (icalfileset *)set;
457 icalfileset_mark(set);
471 fset = (icalfileset *)set;
481 fset = (icalfileset *)set;
491 icalerror_check_arg_rv(set != 0,
"set");
493 fset = (icalfileset *)set;
504 icalerror_check_arg_rz(set != 0,
"set");
505 fset = (icalfileset *)set;
510 icalcomponent *inner;
516 const char *this_uid = icalproperty_get_uid(p);
519 icalerror_warn(
"icalfileset_fetch found a component with no UID");
523 if (strcmp(uid, this_uid) == 0) {
533int icalfileset_has_uid(icalset *set,
const char *uid)
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;
572 id.uid = strdup(icalproperty_get_uid(p));
579 id.sequence = icalproperty_get_sequence(p);
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) {
617icalcomponent *icalfileset_fetch_match(icalset *set,
const icalcomponent *comp)
619 icalfileset *fset = (icalfileset *)set;
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);
658icalcomponent *icalfileset_get_current_component(icalset *set)
662 icalerror_check_arg_rz((set != 0),
"set");
664 fset = (icalfileset *)set;
668icalcomponent *icalfileset_get_first_component(icalset *set)
670 icalcomponent *c = 0;
673 icalerror_check_arg_rz((set != 0),
"set");
674 fset = (icalfileset *)set;
692icalcomponent *icalfileset_get_next_component(icalset *set)
697 icalerror_check_arg_rz((set != 0),
"set");
698 fset = (icalfileset *)set;
745 icalcomponent *comp = NULL;
758 fset = (icalfileset *)set;
773 if (recur != 0 && g == 1) {
777 start = icalproperty_get_dtstart(dtstart);
782 start = icalproperty_get_due(due);
786 if (itr.last_component == NULL) {
789 itr.last_component = comp;
793 itr.last_component = NULL;
798 itr.last_component = comp;
818 if (itr.last_component == NULL) {
826icalcomponent *icalfileset_form_a_matched_recurrence_component(
icalsetiter *itr)
828 icalcomponent *comp = NULL;
830 icalproperty *rrule, *prop;
834 comp = itr->last_component;
836 if (comp == NULL || itr->gauge == NULL) {
841 recur = rrule ? icalproperty_get_rrule(rrule) : NULL;
850 start = icalproperty_get_dtstart(dtstart);
855 start = icalproperty_get_due(due);
859 if (itr->ritr == NULL) {
862 itr->last_component = comp;
867 itr->last_component = NULL;
872 itr->last_component = comp;
892icalcomponent *icalfilesetiter_to_next(icalset *set,
icalsetiter *i)
894 icalcomponent *c = NULL;
896 icalproperty *dtstart, *rrule, *prop, *due;
916 recur = rrule ? icalproperty_get_rrule(rrule) : NULL;
920 if (recur != 0 && g == 1) {
924 start = icalproperty_get_dtstart(dtstart);
929 start = icalproperty_get_due(due);
933 if (i->ritr == NULL) {
936 i->last_component = c;
941 i->last_component = NULL;
946 i->last_component = c;
icalcluster * icalcluster_new(const char *key, icalcomponent *data)
Create a cluster with a key/value pair.
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)
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.
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)
icalfileset_options icalfileset_options_default
icalcomponent * icalfileset_fetch(icalset *set, icalcomponent_kind kind, const char *uid)
Gets and searches for a component by uid.
Manages a database of ical components and offers interfaces for reading, writing and searching for co...
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.