/** * e_cal_util_parse_ics_string: * @string: iCalendar string to be parsed. * * Parses an iCalendar string and returns a new #icalcomponent representing * that string. Note that this function deals with multiple VCALENDAR's in the * string, something that Mozilla used to do and which libical does not * support. * * Returns: a newly created #icalcomponent or NULL if the string isn't a * valid iCalendar string. */ icalcomponent * e_cal_util_parse_ics_string (const gchar *string) { GString *comp_str = NULL; gchar *s; icalcomponent *icalcomp = NULL; g_return_val_if_fail (string != NULL, NULL); /* Split string into separated VCALENDAR's, if more than one */ s = g_strstr_len (string, strlen (string), "BEGIN:VCALENDAR"); if (s == NULL) return icalparser_parse_string (string); while (*s != '\0') { gchar *line = read_line (s); if (!comp_str) comp_str = g_string_new (line); else comp_str = g_string_append (comp_str, line); if (strncmp (line, "END:VCALENDAR", 13) == 0) { icalcomponent *tmp; tmp = icalparser_parse_string (comp_str->str); if (tmp && icalcomponent_isa (tmp) == ICAL_VCALENDAR_COMPONENT) { if (icalcomp) icalcomponent_merge_component (icalcomp, tmp); else icalcomp = tmp; } else { g_warning ( "Could not merge the components, " "the component is either invalid " "or not a toplevel component \n"); } g_string_free (comp_str, TRUE); comp_str = NULL; } s += strlen (line); g_free (line); } return icalcomp; }
GNOKII_API int gn_icalstr2todo(const char * ical, gn_todo *ctodo, int id) { #ifdef HAVE_LIBICAL icalparser *parser = NULL; icalcomponent *comp = NULL; gn_error error; parser = icalparser_new(); if (!parser) { return GN_ERR_FAILED; } comp = icalparser_parse_string (ical); if (!comp) { icalparser_free(parser); return GN_ERR_FAILED; } error = gn_ical2todo_real(comp, ctodo, id); icalcomponent_free(comp); icalparser_free(parser); return error; #else return GN_ERR_NOTIMPLEMENTED; #endif /* HAVE_LIBICAL */ }
/* read a vcalendar event given by id from string ical and store the data in calnote */ GNOKII_API gn_error gn_icalstr2calnote(const char * ical, gn_calnote *calnote, int id) { #ifdef HAVE_LIBICAL icalparser *parser = NULL; icalcomponent *comp = NULL; gn_error retval; parser = icalparser_new(); if (!parser) { return GN_ERR_FAILED; } comp = icalparser_parse_string (ical); if (!comp) { icalparser_free(parser); return GN_ERR_FAILED; } retval = gn_ical2calnote_real(comp, calnote, id); icalcomponent_free(comp); icalparser_free(parser); return retval; #else return GN_ERR_NOTIMPLEMENTED; #endif /* HAVE_LIBICAL */ }
NS_IMETHODIMP calICSService::ParserWorker::Run() { icalcomponent *ical = icalparser_parse_string(PromiseFlatCString(mString).get()); nsresult status = NS_OK; calIIcalComponent *comp = nullptr; if (ical) { comp = new calIcalComponent(ical, nullptr, mProvider); if (!comp) { icalcomponent_free(ical); status = NS_ERROR_OUT_OF_MEMORY; } } else { status = static_cast<nsresult>(calIErrors::ICS_ERROR_BASE + icalerrno); } nsCOMPtr<nsIRunnable> completer = new ParserWorkerCompleter(mWorkerThread, status, comp, mListener); mMainThread->Dispatch(completer, NS_DISPATCH_NORMAL); mWorkerThread = nullptr; mMainThread = nullptr; return NS_OK; }
ScalixAppointment * scalix_appointment_new (const char *calobj) { ScalixAppointment *comp; icalcomponent *icalcomp = NULL; ECalComponent *ecomp; if (calobj != NULL) { icalcomp = icalparser_parse_string (calobj); if (icalcomp == NULL) { return NULL; } } comp = g_object_new (SCALIX_TYPE_APPOINTMENT, NULL); ecomp = E_CAL_COMPONENT (comp); if (icalcomp != NULL) { e_cal_component_set_icalcomponent (ecomp, icalcomp); } return comp; }
NS_IMETHODIMP calICSService::ParseICS(const nsACString& serialized, calITimezoneProvider *tzProvider, calIIcalComponent **component) { NS_ENSURE_ARG_POINTER(component); icalcomponent *ical = icalparser_parse_string(PromiseFlatCString(serialized).get()); if (!ical) { #ifdef DEBUG fprintf(stderr, "Error parsing: '%20s': %d (%s)\n", PromiseFlatCString(serialized).get(), icalerrno, icalerror_strerror(icalerrno)); #endif // The return values is calIError match with ical errors, // so no need for a conversion table or anything. return static_cast<nsresult>(calIErrors::ICS_ERROR_BASE + icalerrno); } calIcalComponent *comp = new calIcalComponent(ical, nullptr, tzProvider); if (!comp) { icalcomponent_free(ical); return NS_ERROR_OUT_OF_MEMORY; } NS_ADDREF(*component = comp); return NS_OK; }
/* Add_timezone handler for the file backend */ static void e_cal_backend_http_add_timezone (ECalBackendSync *backend, EDataCal *cal, GCancellable *cancellable, const gchar *tzobj, GError **error) { ETimezoneCache *timezone_cache; icalcomponent *tz_comp; icaltimezone *zone; timezone_cache = E_TIMEZONE_CACHE (backend); tz_comp = icalparser_parse_string (tzobj); if (!tz_comp) { g_propagate_error (error, EDC_ERROR (InvalidObject)); return; } if (icalcomponent_isa (tz_comp) != ICAL_VTIMEZONE_COMPONENT) { icalcomponent_free (tz_comp); g_propagate_error (error, EDC_ERROR (InvalidObject)); return; } zone = icaltimezone_new (); icaltimezone_set_component (zone, tz_comp); e_timezone_cache_add_timezone (timezone_cache, zone); }
void* icalmime_textcalendar_end_part(void* part) { struct text_part* impl = (struct text_part*) part; icalcomponent *c = icalparser_parse_string(impl->buf); icalmemory_free_buffer(impl->buf); free(impl); return c; }
static gboolean deserialize (ScalixObject * object, const char *string) { ScalixAppointmentPrivate *priv; icalcomponent *icomp, *subcomp; icalcomponent_kind kind; icaltimezone *zone; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { g_warning ("No VCALENAR while deserializing! (%s)\n", string); icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { zone = icaltimezone_new (); icalcomponent_remove_component (icomp, subcomp); if (icaltimezone_set_component (zone, subcomp)) priv->timezone = zone; } kind = ICAL_VEVENT_COMPONENT; /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, kind); if (subcomp == NULL) { icalcomponent_free (icomp); return FALSE; } icalcomponent_remove_component (icomp, subcomp); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); e_cal_component_commit_sequence (E_CAL_COMPONENT (object)); priv->exceptions = NULL; while ((subcomp = icalcomponent_get_next_component (icomp, kind))) { icalcomponent_remove_component (icomp, subcomp); priv->exceptions = g_slist_prepend (priv->exceptions, subcomp); } icalcomponent_free (icomp); return TRUE; }
icalcomponent *record_to_ical(struct mailbox *mailbox, const struct index_record *record) { struct buf buf = BUF_INITIALIZER; icalcomponent *ical = NULL; /* Load message containing the resource and parse iCal data */ if (!mailbox_map_record(mailbox, record, &buf)) { ical = icalparser_parse_string(buf_cstring(&buf) + record->header_size); buf_free(&buf); } return ical; }
static gboolean set_ical_from_mime_part (CamelMimePart * part, ScalixObject * object) { CamelDataWrapper *content; CamelStream *stream; GByteArray *data; icalcomponent *icomp = NULL; icalcomponent *subcomp = NULL; ScalixAppointmentPrivate *priv; priv = SCALIX_APPOINTMENT_GET_PRIVATE (SCALIX_APPOINTMENT (object)); content = camel_medium_get_content_object (CAMEL_MEDIUM (part)); data = g_byte_array_new (); stream = camel_stream_mem_new_with_byte_array (data); camel_data_wrapper_decode_to_stream (content, stream); if (data == NULL || data->data == NULL) { g_print ("Found corrupt ical data\n"); return FALSE; } icomp = icalparser_parse_string ((const char *) data->data); if (icalcomponent_isa (icomp) != ICAL_VCALENDAR_COMPONENT) { icalcomponent_free (icomp); return FALSE; } /* Grab the timezone if any */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VTIMEZONE_COMPONENT); if (subcomp != NULL) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, subcomp); priv->timezone = zone; } /* Grab the main VEVENT */ subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), subcomp); return TRUE; }
int main(int argc, char* argv[]) { char* line; FILE* stream; icalcomponent *c; icalparser *parser = icalparser_new(); long lSize; char *buffer; //while (__AFL_LOOP(1000)){ stream = fopen(argv[1],"r"); fseek( stream , 0L , SEEK_END); lSize = ftell( stream ); rewind( stream ); /* allocate memory for entire content */ buffer = calloc( 1, lSize+1 ); if( !buffer ) fclose(stream),fputs("memory alloc fails",stderr),exit(1); /* copy the file into the buffer */ if( 1!=fread( buffer , lSize, 1 , stream) ) fclose(stream),free(buffer),fputs("entire read fails",stderr),exit(1); icalparser_parse_string(buffer); // icalparser_set_gen_data(parser,stream); // do{ // // line = icalparser_get_line(parser,read_stream); // c = icalparser_add_line(parser,line); // // if (c != 0){ /*icalcomponent_convert_errors(c);*/ // printf("%s",icalcomponent_as_ical_string(c)); // printf("\n---------------\n"); // icalcomponent_free(c); // } // } while ( line != 0); //} return 0; }
static PyObject * cal_IcalToJson(PyObject *self, PyObject *args) { BongoJsonObject *json; icalcomponent *comp; char *str; if (!PyArg_ParseTuple(args, "s", &str)) { PyErr_SetString(PyExc_TypeError, "IcalToJson() takes 2 arguments"); return NULL; } comp = icalparser_parse_string(str); json = BongoCalIcalToJson(comp); icalcomponent_free(comp); return JsonObjectToPy(json, TRUE); }
static gboolean scalix_appointment_from_string (ScalixObject * object, const char *string) { icalcomponent *icomp, *subcomp; icomp = icalparser_parse_string (string); if (icalcomponent_isa (icomp) == ICAL_VCALENDAR_COMPONENT) { subcomp = icalcomponent_get_first_component (icomp, ICAL_VEVENT_COMPONENT); icalcomponent_remove_component (icomp, subcomp); icalcomponent_free (icomp); icomp = subcomp; } e_cal_component_set_icalcomponent (E_CAL_COMPONENT (object), icomp); return TRUE; }
/* This populates a cluster with the entire contents of a database */ static icalerrorenum icalbdbset_read_database(icalbdbset *bset, char *(*pfunc) (const DBT *dbt)) { DB *dbp; DBC *dbcp; DBT key, data; char *str; int ret = EINVAL; char keystore[256]; char datastore[1024]; char *more_mem = NULL; DB_TXN *tid; _unused(pfunc); memset(&key, 0, sizeof(DBT)); memset(&data, 0, sizeof(DBT)); if (bset->sdbp) { dbp = bset->sdbp; } else { dbp = bset->dbp; } if (!dbp) { return ICAL_FILE_ERROR; } bset->cluster = icalcomponent_new(ICAL_XROOT_COMPONENT); if ((ret = ICAL_DB_ENV->txn_begin(ICAL_DB_ENV, NULL, &tid, 0)) != 0) { /*char *foo = db_strerror(ret); */ abort(); } /* acquire a cursor for the database */ if ((ret = dbp->cursor(dbp, tid, &dbcp, 0)) != 0) { dbp->err(dbp, ret, "primary index"); goto err1; } 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); /* fetch the key/data pair */ while (1) { ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT); if (ret == DB_NOTFOUND) { break; } 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) { /*char *foo = db_strerror(ret); */ abort(); /* should retry in case of DB_LOCK_DEADLOCK */ } else if (ret) { /*char *foo = db_strerror(ret); */ /* some other weird-ass error */ dbp->err(dbp, ret, "cursor"); abort(); } else { icalcomponent *cl; /* this prevents an array read bounds error */ if ((str = (char *)calloc(data.size + 1, sizeof(char))) == NULL) { goto err2; } memcpy(str, (char *)data.data, data.size); cl = icalparser_parse_string(str); icalcomponent_add_component(bset->cluster, cl); free(str); } } if (ret != DB_NOTFOUND) { goto err2; } if (more_mem) { free(more_mem); more_mem = NULL; } if ((ret = dbcp->c_close(dbcp)) != 0) { /*char *foo = db_strerror(ret); */ abort(); /* should retry in case of DB_LOCK_DEADLOCK */ } if ((ret = tid->commit(tid, 0)) != 0) { /*char *foo = db_strerror(ret); */ abort(); } return ICAL_NO_ERROR; err2: if (more_mem) { free(more_mem); } dbcp->c_close(dbcp); abort(); /* should retry in case of DB_LOCK_DEADLOCK */ return ICAL_INTERNAL_ERROR; err1: dbp->err(dbp, ret, "cursor index"); abort(); return ICAL_FILE_ERROR; }
static gboolean cal_backend_http_load (ECalBackendHttp *backend, const gchar *uri, gchar **out_certificate_pem, GTlsCertificateFlags *out_certificate_errors, GCancellable *cancellable, GError **error) { ECalBackendHttpPrivate *priv = backend->priv; ETimezoneCache *timezone_cache; SoupMessage *soup_message; SoupSession *soup_session; icalcomponent *icalcomp, *subcomp; icalcomponent_kind kind; const gchar *newuri; SoupURI *uri_parsed; GHashTable *old_cache; GSList *comps_in_cache; ESource *source; guint status_code; gulong cancel_id = 0; struct { SoupSession *soup_session; SoupMessage *soup_message; } cancel_data; timezone_cache = E_TIMEZONE_CACHE (backend); soup_session = backend->priv->soup_session; soup_message = cal_backend_http_new_message (backend, uri); if (soup_message == NULL) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Malformed URI: %s"), uri); return FALSE; } if (G_IS_CANCELLABLE (cancellable)) { cancel_data.soup_session = soup_session; cancel_data.soup_message = soup_message; cancel_id = g_cancellable_connect ( cancellable, G_CALLBACK (cal_backend_http_cancelled), &cancel_data, (GDestroyNotify) NULL); } source = e_backend_get_source (E_BACKEND (backend)); e_soup_ssl_trust_connect (soup_message, source); e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTING); status_code = soup_session_send_message (soup_session, soup_message); if (G_IS_CANCELLABLE (cancellable)) g_cancellable_disconnect (cancellable, cancel_id); if (status_code == SOUP_STATUS_NOT_MODIFIED) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); /* attempts with ETag can result in 304 status code */ g_object_unref (soup_message); priv->opened = TRUE; return TRUE; } /* Handle redirection ourselves */ if (SOUP_STATUS_IS_REDIRECTION (status_code)) { gboolean success; newuri = soup_message_headers_get_list ( soup_message->response_headers, "Location"); d (g_message ("Redirected from %s to %s\n", async_context->uri, newuri)); if (newuri != NULL) { gchar *redirected_uri; if (newuri[0]=='/') { g_warning ("Hey! Relative URI returned! Working around...\n"); uri_parsed = soup_uri_new (uri); soup_uri_set_path (uri_parsed, newuri); soup_uri_set_query (uri_parsed, NULL); /* g_free (newuri); */ newuri = soup_uri_to_string (uri_parsed, FALSE); g_message ("Translated URI: %s\n", newuri); soup_uri_free (uri_parsed); } redirected_uri = webcal_to_http_method (newuri, FALSE); success = cal_backend_http_load ( backend, redirected_uri, out_certificate_pem, out_certificate_errors, cancellable, error); g_free (redirected_uri); } else { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_BAD_REQUEST, _("Redirected to Invalid URI")); success = FALSE; } if (success) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); } else { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); } g_object_unref (soup_message); return success; } /* check status code */ if (!SOUP_STATUS_IS_SUCCESSFUL (status_code)) { /* because evolution knows only G_IO_ERROR_CANCELLED */ if (status_code == SOUP_STATUS_CANCELLED) g_set_error ( error, G_IO_ERROR, G_IO_ERROR_CANCELLED, "%s", soup_message->reason_phrase); else g_set_error ( error, SOUP_HTTP_ERROR, status_code, "%s", soup_message->reason_phrase); if (status_code == SOUP_STATUS_SSL_FAILED) { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_SSL_FAILED); cal_backend_http_extract_ssl_failed_data (soup_message, out_certificate_pem, out_certificate_errors); } else { e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_DISCONNECTED); } g_object_unref (soup_message); empty_cache (backend); return FALSE; } e_source_set_connection_status (source, E_SOURCE_CONNECTION_STATUS_CONNECTED); if (priv->store) { const gchar *etag; etag = soup_message_headers_get_one ( soup_message->response_headers, "ETag"); if (etag != NULL && *etag == '\0') etag = NULL; e_cal_backend_store_put_key_value (priv->store, "ETag", etag); } /* get the calendar from the response */ icalcomp = icalparser_parse_string (soup_message->response_body->data); if (!icalcomp) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Bad file format.")); g_object_unref (soup_message); empty_cache (backend); return FALSE; } if (icalcomponent_isa (icalcomp) != ICAL_VCALENDAR_COMPONENT) { g_set_error ( error, SOUP_HTTP_ERROR, SOUP_STATUS_MALFORMED, _("Not a calendar.")); icalcomponent_free (icalcomp); g_object_unref (soup_message); empty_cache (backend); return FALSE; } g_object_unref (soup_message); soup_message = NULL; /* Update cache */ old_cache = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free); comps_in_cache = e_cal_backend_store_get_components (priv->store); while (comps_in_cache != NULL) { const gchar *uid; ECalComponent *comp = comps_in_cache->data; e_cal_component_get_uid (comp, &uid); g_hash_table_insert (old_cache, g_strdup (uid), e_cal_component_get_as_string (comp)); comps_in_cache = g_slist_remove (comps_in_cache, comps_in_cache->data); g_object_unref (comp); } kind = e_cal_backend_get_kind (E_CAL_BACKEND (backend)); subcomp = icalcomponent_get_first_component (icalcomp, ICAL_ANY_COMPONENT); e_cal_backend_store_freeze_changes (priv->store); while (subcomp) { ECalComponent *comp; icalcomponent_kind subcomp_kind; icalproperty *prop = NULL; subcomp_kind = icalcomponent_isa (subcomp); prop = icalcomponent_get_first_property (subcomp, ICAL_UID_PROPERTY); if (!prop && subcomp_kind == kind) { gchar *new_uid = e_cal_component_gen_uid (); icalcomponent_set_uid (subcomp, new_uid); g_free (new_uid); } if (subcomp_kind == kind) { comp = e_cal_component_new (); if (e_cal_component_set_icalcomponent (comp, icalcomponent_new_clone (subcomp))) { const gchar *uid; gpointer orig_key, orig_value; e_cal_component_get_uid (comp, &uid); if (!put_component_to_store (backend, comp)) { g_hash_table_remove (old_cache, uid); } else if (g_hash_table_lookup_extended (old_cache, uid, &orig_key, &orig_value)) { ECalComponent *orig_comp = e_cal_component_new_from_string (orig_value); e_cal_backend_notify_component_modified (E_CAL_BACKEND (backend), orig_comp, comp); g_hash_table_remove (old_cache, uid); if (orig_comp) g_object_unref (orig_comp); } else { e_cal_backend_notify_component_created (E_CAL_BACKEND (backend), comp); } } g_object_unref (comp); } else if (subcomp_kind == ICAL_VTIMEZONE_COMPONENT) { icaltimezone *zone; zone = icaltimezone_new (); icaltimezone_set_component (zone, icalcomponent_new_clone (subcomp)); e_timezone_cache_add_timezone (timezone_cache, zone); icaltimezone_free (zone, 1); } subcomp = icalcomponent_get_next_component (icalcomp, ICAL_ANY_COMPONENT); } e_cal_backend_store_thaw_changes (priv->store); /* notify the removals */ g_hash_table_foreach_remove (old_cache, (GHRFunc) notify_and_remove_from_cache, backend); g_hash_table_destroy (old_cache); /* free memory */ icalcomponent_free (icalcomp); priv->opened = TRUE; return TRUE; }
/* Add all ZONEs and LINKs in the given directory to the hash table */ void do_zonedir(const char *dir, struct hash_table *tzentries, struct zoneinfo *info) { DIR *dirp; struct dirent *dirent; signals_poll(); if (verbose) printf("Rebuilding %s\n", dir); dirp = opendir(dir); if (!dirp) { fprintf(stderr, "can't open zoneinfo directory %s\n", dir); } while ((dirent = readdir(dirp))) { char path[2048], *tzid; int plen; struct stat sbuf; struct zoneinfo *zi; if (*dirent->d_name == '.') continue; plen = snprintf(path, sizeof(path), "%s/%s", dir, dirent->d_name); lstat(path, &sbuf); if (S_ISDIR(sbuf.st_mode)) { /* Path is a directory (region) */ do_zonedir(path, tzentries, info); } else if (S_ISLNK(sbuf.st_mode)) { /* Path is a symlink (alias) */ char link[1024], *alias; ssize_t llen; /* Isolate tzid in path */ if ((llen = readlink(path, link, sizeof(link))) < 0) continue; link[llen-4] = '\0'; /* Trim ".ics" */ for (tzid = link; !strncmp(tzid, "../", 3); tzid += 3); /* Isolate alias in path */ path[plen-4] = '\0'; /* Trim ".ics" */ alias = path + strlen(config_dir) + strlen("zoneinfo") + 2; if (verbose) printf("\tLINK: %s -> %s\n", alias, tzid); /* Create hash entry for alias */ if (!(zi = hash_lookup(alias, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(alias, zi, tzentries); } zi->type = ZI_LINK; appendstrlist(&zi->data, tzid); /* Create/update hash entry for tzid */ if (!(zi = hash_lookup(tzid, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(tzid, zi, tzentries); } zi->type = ZI_ZONE; appendstrlist(&zi->data, alias); } else if (S_ISREG(sbuf.st_mode)) { /* Path is a regular file (zone) */ int fd; const char *base = NULL; size_t len = 0; icalcomponent *ical, *comp; icalproperty *prop; /* Parse the iCalendar file for important properties */ if ((fd = open(path, O_RDONLY)) == -1) continue; map_refresh(fd, 1, &base, &len, MAP_UNKNOWN_LEN, path, NULL); close(fd); ical = icalparser_parse_string(base); map_free(&base, &len); if (!ical) continue; /* skip non-iCalendar files */ comp = icalcomponent_get_first_component(ical, ICAL_VTIMEZONE_COMPONENT); prop = icalcomponent_get_first_property(comp, ICAL_TZID_PROPERTY); tzid = (char *) icalproperty_get_value_as_string(prop); if (verbose) printf("\tZONE: %s\n", tzid); /* Create/update hash entry for tzid */ if (!(zi = hash_lookup(tzid, tzentries))) { zi = xzmalloc(sizeof(struct zoneinfo)); hash_insert(tzid, zi, tzentries); } zi->type = ZI_ZONE; prop = icalcomponent_get_first_property(comp, ICAL_LASTMODIFIED_PROPERTY); zi->dtstamp = icaltime_as_timet(icalproperty_get_lastmodified(prop)); icalcomponent_free(ical); /* Check overall lastmod */ if (zi->dtstamp > info->dtstamp) info->dtstamp = zi->dtstamp; } else { fprintf(stderr, "unknown path type %s\n", path); } } closedir(dirp); }