if MAN_PAGES_ENABLED
-MAN_IN_FILES = polkit-check-caller.1.in polkit-check-session.1.in polkit-policy-file-validate.1.in PolicyKit.8.in
+MAN_IN_FILES = polkit-check-caller.1.in polkit-check-session.1.in polkit-policy-file-validate.1.in PolicyKit.8.in polkit-reload-config.1.in
man_MANS = $(MAN_IN_FILES:.in=)
--- /dev/null
+.\"
+.\" polkit-reload-config manual page.
+.\" Copyright (C) 2007 David Zeuthen <david@fubar.dk>
+.\"
+.TH POLKIT-RELOAD-CONFIG 1
+.SH NAME
+polkit-reload-config \- reload configuration
+.SH SYNOPSIS
+.PP
+.B polkit-reload-config
+
+.SH DESCRIPTION
+
+\fIpolkit-reload-config\fP can be used to signal all processes using
+libpolkit to reload their configuration. For more information about
+the big picture refer to the \fIPolicyKit spec\fP which can be found
+in
+.I "@docdir@/spec/polkit-spec.html"
+depending on the distribution. Only the super user can invoke this
+tool.
+
+.SH BUGS
+.PP
+Please send bug reports to either the distribution or the HAL
+mailing list, see
+.I "http://lists.freedesktop.org/mailman/listinfo/hal"
+on how to subscribe.
+
+.SH SEE ALSO
+.PP
+\&\fIPolicyKit\fR\|(8)
+
+.SH AUTHOR
+Written by David Zeuthen <david@fubar.dk> with a lot of help from many
+others.
+
clean-local :
rm -f *~ $(BUILT_SOURCES)
+
+# Create /var/lib/PolicyKit/reload file; this is being watched by libpolkit
+# for config file changes.
+install-data-local:
+ touch $(DESTDIR)$(localstatedir)/lib/PolicyKit/reload
+ -chmod 700 $(DESTDIR)$(localstatedir)/lib/PolicyKit/reload
+
#include <grp.h>
#include <unistd.h>
#include <errno.h>
+#include <sys/inotify.h>
#include <glib.h>
#include "polkit-debug.h"
PolKitContextConfigChangedCB config_changed_cb;
void *config_changed_user_data;
- PolKitContextFileMonitorAddWatch file_monitor_add_watch_func;
- PolKitContextFileMonitorRemoveWatch file_monitor_remove_watch_func;
+ PolKitContextAddIOWatch io_add_watch_func;
+ PolKitContextRemoveIOWatch io_remove_watch_func;
char *policy_dir;
PolKitPolicyCache *priv_cache;
polkit_bool_t load_descriptions;
+
+ int inotify_fd;
+ int inotify_fd_watch_id;
+
+ int inotify_reload_wd;
};
/**
pk_context->refcount = 1;
return pk_context;
}
-
-static void
-_config_file_events (PolKitContext *pk_context,
- PolKitContextFileMonitorEvent event_mask,
- const char *path,
- void *user_data)
-{
- _pk_debug ("Config file changed");
-
- /* signal that our configuration (may have) changed */
- if (pk_context->config_changed_cb) {
- pk_context->config_changed_cb (pk_context, pk_context->config_changed_user_data);
- }
-}
-
-static void
-_policy_dir_events (PolKitContext *pk_context,
- PolKitContextFileMonitorEvent event_mask,
- const char *path,
- void *user_data)
-{
- /* mark cache of policy files as stale.. (will be populated on-demand, see _get_cache()) */
- if (pk_context->priv_cache != NULL) {
- _pk_debug ("Something happened in %s - invalidating cache", pk_context->policy_dir);
- polkit_policy_cache_unref (pk_context->priv_cache);
- pk_context->priv_cache = NULL;
- }
-
- /* signal that our configuration (may have) changed */
- if (pk_context->config_changed_cb) {
- pk_context->config_changed_cb (pk_context, pk_context->config_changed_user_data);
- }
-}
-
/**
* polkit_context_init:
* @pk_context: the context object
}
_pk_debug ("Using policy files from directory %s", pk_context->policy_dir);
- /* don't populate the cache until it's needed.. */
+ /* we don't populate the cache until it's needed.. */
+ if (pk_context->io_add_watch_func != NULL) {
+ pk_context->inotify_fd = inotify_init ();
+ if (pk_context->inotify_fd < 0) {
+ _pk_debug ("failed to initialize inotify: %s", strerror (errno));
+ /* TODO: set error */
+ goto error;
+ }
- if (pk_context->file_monitor_add_watch_func == NULL) {
- _pk_debug ("No file monitor; cannot monitor '%s' for .policy file changes", pk_context->policy_dir);
- } else {
- /* Watch when policy definitions file change */
- pk_context->file_monitor_add_watch_func (pk_context,
- pk_context->policy_dir,
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE|
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE|
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE,
- _policy_dir_events,
- NULL);
-
- /* Config file changes */
- pk_context->file_monitor_add_watch_func (pk_context,
- PACKAGE_DATA_DIR "/PolicyKit",
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE|
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE|
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE,
- _config_file_events,
- NULL);
+ /* create a watch on /var/lib/PolicyKit/reload */
+ pk_context->inotify_reload_wd = inotify_add_watch (pk_context->inotify_fd,
+ PACKAGE_LOCALSTATEDIR "/lib/PolicyKit/reload",
+ IN_MODIFY | IN_CREATE | IN_ATTRIB);
+ if (pk_context->inotify_reload_wd < 0) {
+ _pk_debug ("failed to add watch on file '" PACKAGE_LOCALSTATEDIR "/lib/PolicyKit/reload': %s",
+ strerror (errno));
+ /* TODO: set error */
+ goto error;
+ }
+
+ pk_context->inotify_fd_watch_id = pk_context->io_add_watch_func (pk_context, pk_context->inotify_fd);
+ if (pk_context->inotify_fd_watch_id == 0) {
+ _pk_debug ("failed to add io watch");
+ /* TODO: set error */
+ goto error;
+ }
}
return TRUE;
-#if 0
error:
if (pk_context != NULL)
polkit_context_unref (pk_context);
return FALSE;
-#endif
}
/**
**/
void
polkit_context_set_config_changed (PolKitContext *pk_context,
- PolKitContextConfigChangedCB cb,
- void *user_data)
+ PolKitContextConfigChangedCB cb,
+ void *user_data)
{
g_return_if_fail (pk_context != NULL);
pk_context->config_changed_cb = cb;
}
/**
- * polkit_context_set_file_monitor:
+ * polkit_context_io_func:
+ * @pk_context: the object
+ * @fd: the file descriptor passed to the supplied function of type #PolKitContextAddIOWatch.
+ *
+ * Method that the application must call when there is data to read
+ * from a file descriptor registered with the supplied function of
+ * type #PolKitContextAddIOWatch.
+ **/
+void
+polkit_context_io_func (PolKitContext *pk_context, int fd)
+{
+ g_return_if_fail (pk_context != NULL);
+
+ _pk_debug ("polkit_context_io_func: data on fd %d", fd);
+
+ if (fd == pk_context->inotify_fd) {
+/* size of the event structure, not counting name */
+#define EVENT_SIZE (sizeof (struct inotify_event))
+/* reasonable guess as to size of 1024 events */
+#define BUF_LEN (1024 * (EVENT_SIZE + 16))
+ char buf[BUF_LEN];
+ int len;
+ int i = 0;
+again:
+ len = read (fd, buf, BUF_LEN);
+ if (len < 0) {
+ if (errno == EINTR) {
+ goto again;
+ } else {
+ _pk_debug ("read: %s", strerror (errno));
+ }
+ } else if (len > 0) {
+ /* BUF_LEN too small? */
+ }
+ while (i < len) {
+ struct inotify_event *event;
+ event = (struct inotify_event *) &buf[i];
+ _pk_debug ("wd=%d mask=%u cookie=%u len=%u",
+ event->wd, event->mask, event->cookie, event->len);
+
+ if (event->wd == pk_context->inotify_reload_wd) {
+ _pk_debug ("config changed!");
+ if (pk_context->config_changed_cb != NULL) {
+ pk_context->config_changed_cb (pk_context,
+ pk_context->config_changed_user_data);
+ }
+ }
+
+ i += EVENT_SIZE + event->len;
+ }
+ }
+}
+
+/**
+ * polkit_context_set_io_watch_functions:
* @pk_context: the context object
- * @add_watch_func: the function that the PolicyKit library can invoke to start watching a file
- * @remove_watch_func: the function that the PolicyKit library can invoke to stop watching a file
+ * @io_add_watch_func: the function that the PolicyKit library can invoke to start watching a file descriptor
+ * @io_remove_watch_func: the function that the PolicyKit library can invoke to stop watching a file descriptor
*
- * Register a functions that PolicyKit can use for watching files.
+ * Register a functions that PolicyKit can use for watching IO descriptors.
*
* This method must be called before polkit_context_init().
**/
void
-polkit_context_set_file_monitor (PolKitContext *pk_context,
- PolKitContextFileMonitorAddWatch add_watch_func,
- PolKitContextFileMonitorRemoveWatch remove_watch_func)
+polkit_context_set_io_watch_functions (PolKitContext *pk_context,
+ PolKitContextAddIOWatch io_add_watch_func,
+ PolKitContextRemoveIOWatch io_remove_watch_func)
{
g_return_if_fail (pk_context != NULL);
- pk_context->file_monitor_add_watch_func = add_watch_func;
- pk_context->file_monitor_remove_watch_func = remove_watch_func;
+ pk_context->io_add_watch_func = io_add_watch_func;
+ pk_context->io_remove_watch_func = io_remove_watch_func;
}
/**
* permissions / acl's they have set in response to policy decisions
* made from information provided by PolicyKit.
*
+ * The user must have set up watches using #polkit_context_set_io_watch_functions
+ * for this to work.
+ *
* Note that this function may be called many times within a short
* interval due to how file monitoring works if e.g. the user is
* editing a configuration file (editors typically create back-up
void *user_data);
/**
- * PolKitContextFileMonitorEvent:
- * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_NONE: TODO
- * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_ACCESS: watch when a file is accessed
- * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE: watch when a file is created
- * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE: watch when a file is deleted
- * @POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE: watch when a file changes
- *
- * File monitoring events.
- **/
-typedef enum
-{
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_NONE = 1 << 0,
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_ACCESS = 1 << 1,
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CREATE = 1 << 2,
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_DELETE = 1 << 3,
- POLKIT_CONTEXT_FILE_MONITOR_EVENT_CHANGE = 1 << 4,
-} PolKitContextFileMonitorEvent;
-
-/**
- * PolKitContextFileMonitorNotifyFunc:
- * @pk_context: PolicyKit context
- * @event_mask: event that happened
- * @path: the path to the monitored file
- * @user_data: the user data supplied to the function of type #PolKitContextFileMonitorAddWatch
+ * PolKitContextAddIOWatch:
+ * @pk_context: the polkit context
+ * @fd: the file descriptor to watch
*
- * Callback when an event happens on a file that is monitored.
+ * Type for function supplied by the application to integrate a watch
+ * on a file descriptor into the applications main loop. The
+ * application must call polkit_grant_io_func() when there is data
+ * to read from the file descriptor.
+ *
+ * For glib mainloop, the function will typically look like this:
+ *
+ * <programlisting>
+ * static gboolean
+ * io_watch_have_data (GIOChannel *channel, GIOCondition condition, gpointer user_data)
+ * {
+ * int fd;
+ * PolKitContext *pk_context = user_data;
+ * fd = g_io_channel_unix_get_fd (channel);
+ * polkit_context_io_func (pk_context, fd);
+ * return TRUE;
+ * }
+ *
+ * static int
+ * io_add_watch (PolKitContext *pk_context, int fd)
+ * {
+ * guint id = 0;
+ * GIOChannel *channel;
+ * channel = g_io_channel_unix_new (fd);
+ * if (channel == NULL)
+ * goto out;
+ * id = g_io_add_watch (channel, G_IO_IN, io_watch_have_data, pk_context);
+ * if (id == 0) {
+ * g_io_channel_unref (channel);
+ * goto out;
+ * }
+ * g_io_channel_unref (channel);
+ * out:
+ * return id;
+ * }
+ * </programlisting>
+ *
+ * Returns: 0 if the watch couldn't be set up; otherwise an unique
+ * identifier for the watch.
**/
-typedef void (*PolKitContextFileMonitorNotifyFunc) (PolKitContext *pk_context,
- PolKitContextFileMonitorEvent event_mask,
- const char *path,
- void *user_data);
+typedef int (*PolKitContextAddIOWatch) (PolKitContext *pk_context, int fd);
/**
- * PolKitContextFileMonitorAddWatch:
- * @pk_context: PolicyKit context
- * @path: path to file/directory to monitor for events
- * @event_mask: events to look for
- * @notify_cb: function to call on events
- * @user_data: user data
+ * PolKitContextRemoveIOWatch:
+ * @pk_context: the context object
+ * @watch_id: the id obtained from using the supplied function
+ * of type #PolKitContextAddIOWatch
*
- * The type of a function that PolicyKit can use to watch file
- * events. This function must call the supplied @notify_cb function
- * (and pass @path and @user_data) on events
+ * Type for function supplied by the application to remove a watch set
+ * up via the supplied function of type #PolKitContextAddIOWatch
*
- * Returns: A handle for the watch. If zero it means the file cannot
- * be watched. Caller can remove the watch using the supplied function
- * of type #PolKitContextFileMonitorRemoveWatch and the handle.
- */
-typedef int (*PolKitContextFileMonitorAddWatch) (PolKitContext *pk_context,
- const char *path,
- PolKitContextFileMonitorEvent event_mask,
- PolKitContextFileMonitorNotifyFunc notify_cb,
- void *user_data);
-
-/**
- * PolKitContextFileMonitorRemoveWatch:
- * @pk_context: PolicyKit context
- * @watch_id: the watch id
+ * For the glib mainloop, the function will typically look like this:
*
- * The type of a function that PolicyKit can use to stop monitoring
- * file events. Pass the handle obtained from the supplied function of
- * type #PolKitContextFileMonitorAddWatch.
- */
-typedef void (*PolKitContextFileMonitorRemoveWatch) (PolKitContext *pk_context,
- int watch_id);
+ * <programlisting>
+ * static void
+ * io_remove_watch (PolKitContext *pk_context, int watch_id)
+ * {
+ * g_source_remove (watch_id);
+ * }
+ * </programlisting>
+ *
+ **/
+typedef void (*PolKitContextRemoveIOWatch) (PolKitContext *pk_context, int watch_id);
+
+PolKitContext *polkit_context_new (void);
+void polkit_context_set_config_changed (PolKitContext *pk_context,
+ PolKitContextConfigChangedCB cb,
+ void *user_data);
+void polkit_context_set_io_watch_functions (PolKitContext *pk_context,
+ PolKitContextAddIOWatch io_add_watch_func,
+ PolKitContextRemoveIOWatch io_remove_watch_func);
+void polkit_context_set_load_descriptions (PolKitContext *pk_context);
+polkit_bool_t polkit_context_init (PolKitContext *pk_context,
+ PolKitError **error);
+PolKitContext *polkit_context_ref (PolKitContext *pk_context);
+void polkit_context_unref (PolKitContext *pk_context);
-PolKitContext *polkit_context_new (void);
-void polkit_context_set_config_changed (PolKitContext *pk_context,
- PolKitContextConfigChangedCB cb,
- void *user_data);
-void polkit_context_set_file_monitor (PolKitContext *pk_context,
- PolKitContextFileMonitorAddWatch add_watch_func,
- PolKitContextFileMonitorRemoveWatch remove_watch_func);
-void polkit_context_set_load_descriptions (PolKitContext *pk_context);
-polkit_bool_t polkit_context_init (PolKitContext *pk_context,
- PolKitError **error);
-PolKitContext *polkit_context_ref (PolKitContext *pk_context);
-void polkit_context_unref (PolKitContext *pk_context);
+void polkit_context_io_func (PolKitContext *pk_context, int fd);
-PolKitPolicyCache *polkit_context_get_policy_cache (PolKitContext *pk_context);
+PolKitPolicyCache *polkit_context_get_policy_cache (PolKitContext *pk_context);
PolKitResult
-polkit_context_can_session_do_action (PolKitContext *pk_context,
- PolKitAction *action,
- PolKitSession *session);
+polkit_context_can_session_do_action (PolKitContext *pk_context,
+ PolKitAction *action,
+ PolKitSession *session);
PolKitResult
-polkit_context_can_caller_do_action (PolKitContext *pk_context,
- PolKitAction *action,
- PolKitCaller *caller);
+polkit_context_can_caller_do_action (PolKitContext *pk_context,
+ PolKitAction *action,
+ PolKitCaller *caller);
#endif /* POLKIT_CONTEXT_H */
bin_PROGRAMS = polkit-check-caller polkit-check-session polkit-policy-file-validate polkit-grant polkit-list-actions
+bin_SCRIPTS = polkit-reload-config
+
polkit_check_caller_SOURCES = polkit-check-caller.c
polkit_check_caller_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ $(top_builddir)/polkit/libpolkit.la $(top_builddir)/polkit-dbus/libpolkit-dbus.la
polkit_list_actions_SOURCES = polkit-list-actions.c
polkit_list_actions_LDADD = $(GLIB) $(top_builddir)/polkit/libpolkit.la
+polkit-reload-config: polkit-reload-config.in Makefile
+ $(edit) $< >$@
+
+edit = sed \
+ -e 's|@docdir[@]|$(docdir)|g' \
+ -e 's|@sbindir[@]|$(sbindir)|g' \
+ -e 's|@sysconfdir[@]|$(sysconfdir)|g' \
+ -e 's|@datadir[@]|$(datadir)|g' \
+ -e 's|@localstatedir[@]|$(localstatedir)|g'
+
clean-local :
rm -f *~
--- /dev/null
+#!/bin/sh
+touch @localstatedir@/lib/PolicyKit/reload