/** * e2k_freebusy_add_from_calendar_uri: * @fb: an #E2kFreebusy * @uri: the URI of a calendar folder * @start_tt: start of the range to add * @end_tt: end of the range to add * * This queries the server for events between @start_tt and @end_tt in * the calendar at @uri (which the caller must have permission to * read) and adds them @fb. Any previously-existing events during that * range are removed. * * Return value: an HTTP status code. **/ E2kHTTPStatus e2k_freebusy_add_from_calendar_uri (E2kFreebusy *fb, const char *uri, time_t start_tt, time_t end_tt) { char *start, *end, *busystatus; E2kBusyStatus busy; E2kRestriction *rn; E2kResultIter *iter; E2kResult *result; e2k_freebusy_clear_interval (fb, start_tt, end_tt); start = e2k_make_timestamp (start_tt); end = e2k_make_timestamp (end_tt); rn = e2k_restriction_andv ( e2k_restriction_prop_string (E2K_PR_DAV_CONTENT_CLASS, E2K_RELOP_EQ, "urn:content-classes:appointment"), e2k_restriction_prop_date (E2K_PR_CALENDAR_DTEND, E2K_RELOP_GT, start), e2k_restriction_prop_date (E2K_PR_CALENDAR_DTSTART, E2K_RELOP_LT, end), e2k_restriction_prop_string (E2K_PR_CALENDAR_BUSY_STATUS, E2K_RELOP_NE, "FREE"), NULL); iter = e2k_context_search_start (fb->ctx, NULL, uri, freebusy_props, n_freebusy_props, rn, NULL, TRUE); e2k_restriction_unref (rn); g_free (start); g_free (end); while ((result = e2k_result_iter_next (iter))) { start = e2k_properties_get_prop (result->props, E2K_PR_CALENDAR_DTSTART); end = e2k_properties_get_prop (result->props, E2K_PR_CALENDAR_DTEND); busystatus = e2k_properties_get_prop (result->props, E2K_PR_CALENDAR_BUSY_STATUS); if (!start || !end || !busystatus) continue; if (!strcmp (busystatus, "TENTATIVE")) busy = E2K_BUSYSTATUS_TENTATIVE; else if (!strcmp (busystatus, "OUTOFOFFICE")) busy = E2K_BUSYSTATUS_OOF; else busy = E2K_BUSYSTATUS_BUSY; e2k_freebusy_add_interval (fb, busy, e2k_parse_timestamp (start), e2k_parse_timestamp (end)); } return e2k_result_iter_free (iter); }
/* Fetch the list of delegates from the freebusy message. */ static gboolean get_user_list (ExchangeDelegates *delegates) { E2kContext *ctx; E2kResultIter *iter; E2kResult *result; GPtrArray *display_names, *entryids, *privflags; GByteArray *entryid; ExchangeDelegatesUser *user; gint i; ctx = exchange_account_get_context (delegates->account); iter = e2k_context_bpropfind_start (ctx, NULL, delegates->account->home_uri, &exchange_localfreebusy_path, 1, delegation_props, G_N_ELEMENTS (delegation_props)); result = e2k_result_iter_next (iter); if (!result || !E2K_HTTP_STATUS_IS_SUCCESSFUL (result->status)) { e2k_result_iter_free (iter); return FALSE; } delegates->users = g_ptr_array_new (); delegates->added_users = g_ptr_array_new (); delegates->removed_users = g_ptr_array_new (); display_names = e2k_properties_get_prop (result->props, PR_DELEGATES_DISPLAY_NAMES); entryids = e2k_properties_get_prop (result->props, PR_DELEGATES_ENTRYIDS); privflags = e2k_properties_get_prop (result->props, PR_DELEGATES_SEE_PRIVATE); entryid = e2k_properties_get_prop (result->props, PR_CREATOR_ENTRYID); delegates->creator_entryid = g_byte_array_new (); g_byte_array_append (delegates->creator_entryid, entryid->data, entryid->len); if (!display_names || !entryids || !privflags) { e2k_result_iter_free (iter); return TRUE; } for (i = 0; i < display_names->len && i < entryids->len && i < privflags->len; i++) { user = exchange_delegates_user_new (display_names->pdata[i]); user->see_private = privflags->pdata[i] && atoi (privflags->pdata[i]); entryid = entryids->pdata[i]; user->entryid = g_byte_array_new (); g_byte_array_append (user->entryid, entryid->data, entryid->len); g_signal_connect (user, "edited", G_CALLBACK (set_perms_for_user), delegates); g_ptr_array_add (delegates->users, user); } e2k_result_iter_free (iter); return TRUE; }
void test_main (gint argc, gchar **argv) { const gchar *url; E2kContext *ctx; E2kHTTPStatus status; E2kResult *results; gint nresults; GByteArray *ba; E2kRules *rules; xmlDoc *doc; if (argc != 2) { fprintf (stderr, "Usage: %s URL\n", argv[0]); exit (1); } url = argv[1]; ctx = test_get_context (url); status = e2k_context_propfind (ctx, NULL, url, rules_props, G_N_ELEMENTS (rules_props), &results, &nresults); test_abort_if_http_error (status); ba = e2k_properties_get_prop (results[0].props, PR_RULES_DATA); if (!ba) { printf ("No rules\n"); goto done; } rules = e2k_rules_from_binary (ba); if (!rules) { printf ("Could not parse rules\n"); goto done; } doc = e2k_rules_to_xml (rules); if (doc) { xmlDocFormatDump (stdout, doc, TRUE); xmlFreeDoc (doc); } else printf ("Could not convert normal rules to XML\n"); e2k_rules_free (rules); e2k_results_free (results, nresults); done: test_quit (); }
/* Read the folder security descriptors and match them up with the * list of delegates. */ static gboolean get_folder_security (ExchangeDelegates *delegates) { GPtrArray *hrefs; E2kContext *ctx; E2kHTTPStatus status; E2kResultIter *iter; E2kResult *result; xmlNode *xml_form; GByteArray *binary_form; ExchangeDelegatesUser *user; guint32 perms; gint i, u; /* If we've been here before, just return the success or * failure result from last time. */ if (delegates->freebusy_folder.uri) return delegates->loaded_folders; if (!exchange_account_get_global_catalog (delegates->account)) { e_alert_run_dialog_for_args (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":delegates-no-gcs-error", NULL); return FALSE; } ctx = exchange_account_get_context (delegates->account); hrefs = g_ptr_array_new (); for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { delegates->folder[i].uri = exchange_account_get_standard_uri ( delegates->account, exchange_delegates_user_folder_names[i]); if (delegates->folder[i].uri) { g_ptr_array_add (hrefs, (gchar *) e2k_uri_relative ( delegates->account->home_uri, delegates->folder[i].uri)); } } g_ptr_array_add (hrefs, (gchar *) exchange_localfreebusy_path); iter = e2k_context_bpropfind_start ( ctx, NULL, delegates->account->home_uri, (const gchar **) hrefs->pdata, hrefs->len, sd_props, G_N_ELEMENTS (sd_props)); g_ptr_array_free (hrefs, TRUE); while ((result = e2k_result_iter_next (iter))) { xml_form = e2k_properties_get_prop (result->props, E2K_PR_EXCHANGE_SD_XML); binary_form = e2k_properties_get_prop (result->props, E2K_PR_EXCHANGE_SD_BINARY); if (xml_form && binary_form) { set_sd_for_href (delegates, result->href, e2k_security_descriptor_new (xml_form, binary_form)); } } status = e2k_result_iter_free (iter); if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status)) { e_alert_run_dialog_for_args (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":delegates-perm-read-error", NULL); return FALSE; } if (!fill_in_sids (delegates)) { delegates->loaded_folders = FALSE; e_alert_run_dialog_for_args (GTK_WINDOW (delegates->table), ERROR_DOMAIN ":perm-deter-error", NULL); return FALSE; } /* Fill in delegate structures from the security descriptors */ for (i = 0; i < EXCHANGE_DELEGATES_LAST; i++) { for (u = 0; u < delegates->users->len; u++) { user = delegates->users->pdata[u]; perms = e2k_security_descriptor_get_permissions ( delegates->folder[i].sd, user->sid); user->role[i] = e2k_permissions_role_find (perms); } } delegates->loaded_folders = TRUE; return TRUE; }
/** * e2k_freebusy_new: * @ctx: an #E2kContext * @public_uri: the URI of the MAPI public folder tree * @dn: the legacy Exchange DN of a user * * Creates a new #E2kFreebusy, filled in with information from the * indicated user's published free/busy information. This uses the * public free/busy folder; the caller does not need permission to * access the @dn's Calendar. * * Note that currently, this will fail and return %NULL if the user * does not already have free/busy information stored on the server. * * Return value: the freebusy information **/ E2kFreebusy * e2k_freebusy_new (E2kContext *ctx, const char *public_uri, const char *dn) { E2kFreebusy *fb; char *uri, *time; GPtrArray *monthyears, *fbdatas; E2kHTTPStatus status; E2kResult *results; int nresults = 0, i; uri = fb_uri_for_dn (public_uri, dn); g_return_val_if_fail (uri, NULL); status = e2k_context_propfind (ctx, NULL, uri, public_freebusy_props, n_public_freebusy_props, &results, &nresults); if (!E2K_HTTP_STATUS_IS_SUCCESSFUL (status) || nresults == 0) { /* FIXME: create it */ g_free (uri); return NULL; } fb = g_new0 (E2kFreebusy, 1); fb->uri = uri; fb->dn = g_strdup (dn); fb->ctx = ctx; g_object_ref (ctx); for (i = 0; i < E2K_BUSYSTATUS_MAX; i++) fb->events[i] = g_array_new (FALSE, FALSE, sizeof (E2kFreebusyEvent)); time = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_START_RANGE); fb->start = time ? e2k_systime_to_time_t (strtol (time, NULL, 10)) : 0; time = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_END_RANGE); fb->end = time ? e2k_systime_to_time_t (strtol (time, NULL, 10)) : 0; monthyears = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_ALL_MONTHS); fbdatas = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_ALL_EVENTS); add_data_for_status (fb, monthyears, fbdatas, fb->events[E2K_BUSYSTATUS_ALL]); monthyears = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_TENTATIVE_MONTHS); fbdatas = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_TENTATIVE_EVENTS); add_data_for_status (fb, monthyears, fbdatas, fb->events[E2K_BUSYSTATUS_TENTATIVE]); monthyears = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_BUSY_MONTHS); fbdatas = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_BUSY_EVENTS); add_data_for_status (fb, monthyears, fbdatas, fb->events[E2K_BUSYSTATUS_BUSY]); monthyears = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_OOF_MONTHS); fbdatas = e2k_properties_get_prop ( results[0].props, PR_FREEBUSY_OOF_EVENTS); add_data_for_status (fb, monthyears, fbdatas, fb->events[E2K_BUSYSTATUS_OOF]); e2k_results_free (results, nresults); return fb; }