/*
- * "$Id$"
+ * "$Id: dbus.c 11500 2014-01-06 22:21:15Z msweet $"
*
- * D-Bus notifier for CUPS.
+ * D-Bus notifier for CUPS.
*
- * Copyright 2008-2010 by Apple Inc.
- * Copyright (C) 2011 Red Hat, Inc.
- * Copyright (C) 2007 Tim Waugh <twaugh@redhat.com>
- * Copyright 1997-2005 by Easy Software Products.
+ * Copyright 2008-2014 by Apple Inc.
+ * Copyright (C) 2011, 2013 Red Hat, Inc.
+ * Copyright (C) 2007 Tim Waugh <twaugh@redhat.com>
+ * Copyright 1997-2005 by Easy Software Products.
*
- * These coded instructions, statements, and computer programs are the
- * property of Apple Inc. and are protected by Federal copyright
- * law. Distribution and use rights are outlined in the file "LICENSE.txt"
- * which should have been included with this file. If this file is
- * file is missing or damaged, see the license at "http://www.cups.org/".
- *
- * Contents:
- *
- * main() - Read events and send DBUS notifications.
- * acquire_lock() - Acquire a lock so we only have a single notifier running.
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law. Distribution and use rights are outlined in the file "LICENSE.txt"
+ * which should have been included with this file. If this file is
+ * file is missing or damaged, see the license at "http://www.cups.org/".
*/
/*
#include <sys/types.h>
#include <unistd.h>
-#include <dbus/dbus.h>
-#ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND
-# define dbus_message_append_iter_init dbus_message_iter_init_append
-# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, v)
-# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, v)
-# define dbus_message_iter_append_boolean(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, v)
-#endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */
+#ifdef HAVE_DBUS
+# include <dbus/dbus.h>
+# ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND
+# define dbus_message_append_iter_init dbus_message_iter_init_append
+# define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, v)
+# define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, v)
+# define dbus_message_iter_append_boolean(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, v)
+# endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */
/*
};
+/*
+ * Global variables...
+ */
+
+static char lock_filename[1024]; /* Lock filename */
+
+
/*
* Local functions...
*/
static int acquire_lock(int *fd, char *lockfile, size_t locksize);
+static void release_lock(void);
/*
DBusMessage *message; /* Message to send */
DBusMessageIter iter; /* Iterator for message data */
int lock_fd = -1; /* Lock file descriptor */
- char lock_filename[1024];
- /* Lock filename */
/*
const char *signame = NULL;/* DBUS signal name */
char *printer_reasons = NULL;
/* Printer reasons string */
+ char *job_reasons = NULL;
+ /* Job reasons string */
const char *nul = ""; /* Empty string value */
int no = 0; /* Boolean "no" value */
int params = PARAMS_NONE;
continue;
attr = ippFindAttribute(msg, "notify-subscribed-event",
- IPP_TAG_KEYWORD);
+ IPP_TAG_KEYWORD);
if (!attr)
continue;
- event = attr->values[0].string.text;
+ event = ippGetString(attr, 0, NULL);
if (!strncmp(event, "server-", 7))
{
const char *word2 = event + 7; /* Second word */
dbus_message_append_iter_init(message, &iter);
attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT);
- if (!attr)
+ if (attr)
+ {
+ const char *val = ippGetString(attr, 0, NULL);
+ if (!dbus_message_iter_append_string(&iter, &val))
+ goto bail;
+ }
+ else
goto bail;
- dbus_message_iter_append_string(&iter, &(attr->values[0].string.text));
if (params >= PARAMS_PRINTER)
{
/* STRING printer-uri or "" */
attr = ippFindAttribute(msg, "notify-printer-uri", IPP_TAG_URI);
if (attr)
- dbus_message_iter_append_string(&iter, &(attr->values[0].string.text));
+ {
+ const char *val = ippGetString(attr, 0, NULL);
+ if (!dbus_message_iter_append_string(&iter, &val))
+ goto bail;
+ }
else
{
have_printer_params = 0;
if (have_printer_params)
{
attr = ippFindAttribute(msg, "printer-name", IPP_TAG_NAME);
- if (attr)
- dbus_message_iter_append_string(&iter,
- &(attr->values[0].string.text));
- else
- goto bail;
+ if (attr)
+ {
+ const char *val = ippGetString(attr, 0, NULL);
+ if (!dbus_message_iter_append_string(&iter, &val))
+ goto bail;
+ }
+ else
+ goto bail;
}
else
dbus_message_iter_append_string(&iter, &nul);
{
attr = ippFindAttribute(msg, "printer-state", IPP_TAG_ENUM);
if (attr)
- dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer));
+ {
+ dbus_uint32_t val = ippGetInteger(attr, 0);
+ dbus_message_iter_append_uint32(&iter, &val);
+ }
else
goto bail;
}
IPP_TAG_KEYWORD);
if (attr)
{
- for (reasons_length = 0, i = 0; i < attr->num_values; i++)
+ int num_values = ippGetCount(attr);
+ for (reasons_length = 0, i = 0; i < num_values; i++)
/* All need commas except the last, which needs a nul byte. */
- reasons_length += 1 + strlen(attr->values[i].string.text);
+ reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
printer_reasons = malloc(reasons_length);
if (!printer_reasons)
goto bail;
p = printer_reasons;
- for (i = 0; i < attr->num_values; i++)
+ for (i = 0; i < num_values; i++)
{
if (i)
*p++ = ',';
- strcpy(p, attr->values[i].string.text);
+ strlcpy(p, ippGetString(attr, i, NULL),
+ reasons_length - (p - printer_reasons));
p += strlen(p);
}
- dbus_message_iter_append_string(&iter, &printer_reasons);
+ if (!dbus_message_iter_append_string(&iter, &printer_reasons))
+ goto bail;
}
else
goto bail;
attr = ippFindAttribute(msg, "printer-is-accepting-jobs",
IPP_TAG_BOOLEAN);
if (attr)
- dbus_message_iter_append_boolean(&iter, &(attr->values[0].boolean));
+ {
+ dbus_bool_t val = ippGetBoolean(attr, 0);
+ dbus_message_iter_append_boolean(&iter, &val);
+ }
else
goto bail;
}
if (params >= PARAMS_JOB)
{
+ char *p; /* Pointer into job_reasons */
+ size_t reasons_length; /* Required size of job_reasons */
+ int i; /* Looping var */
+
/* UINT32 job-id */
attr = ippFindAttribute(msg, "notify-job-id", IPP_TAG_INTEGER);
- if (!attr)
+ if (attr)
+ {
+ dbus_uint32_t val = ippGetInteger(attr, 0);
+ dbus_message_iter_append_uint32(&iter, &val);
+ }
+ else
goto bail;
- dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer));
/* UINT32 job-state */
attr = ippFindAttribute(msg, "job-state", IPP_TAG_ENUM);
- if (!attr)
+ if (attr)
+ {
+ dbus_uint32_t val = ippGetInteger(attr, 0);
+ dbus_message_iter_append_uint32(&iter, &val);
+ }
+ else
goto bail;
- dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer));
/* STRING job-state-reasons */
attr = ippFindAttribute(msg, "job-state-reasons", IPP_TAG_KEYWORD);
- if (!attr)
+ if (attr)
+ {
+ int num_values = ippGetCount(attr);
+ for (reasons_length = 0, i = 0; i < num_values; i++)
+ /* All need commas except the last, which needs a nul byte. */
+ reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
+ job_reasons = malloc(reasons_length);
+ if (!job_reasons)
+ goto bail;
+ p = job_reasons;
+ for (i = 0; i < num_values; i++)
+ {
+ if (i)
+ *p++ = ',';
+
+ strlcpy(p, ippGetString(attr, i, NULL),
+ reasons_length - (p - job_reasons));
+ p += strlen(p);
+ }
+ if (!dbus_message_iter_append_string(&iter, &job_reasons))
+ goto bail;
+ }
+ else
goto bail;
- dbus_message_iter_append_string(&iter, &(attr->values[0].string.text));
/* STRING job-name or "" */
attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME);
if (attr)
- dbus_message_iter_append_string(&iter, &(attr->values[0].string.text));
+ {
+ const char *val = ippGetString(attr, 0, NULL);
+ if (!dbus_message_iter_append_string(&iter, &val))
+ goto bail;
+ }
else
dbus_message_iter_append_string(&iter, &nul);
/* UINT32 job-impressions-completed */
attr = ippFindAttribute(msg, "job-impressions-completed",
IPP_TAG_INTEGER);
- if (!attr)
+ if (attr)
+ {
+ dbus_uint32_t val = ippGetInteger(attr, 0);
+ dbus_message_iter_append_uint32(&iter, &val);
+ }
+ else
goto bail;
- dbus_message_iter_append_uint32(&iter, &(attr->values[0].integer));
}
dbus_connection_send(con, message, NULL);
bail:
+ dbus_message_unref(message);
+
if (printer_reasons)
free(printer_reasons);
- dbus_message_unref(message);
+ if (job_reasons)
+ free(job_reasons);
+
ippDelete(msg);
}
if (lock_fd >= 0)
{
close(lock_fd);
- unlink(lock_filename);
+ release_lock();
}
return (0);
}
+/*
+ * 'release_lock()' - Release the singleton lock.
+ */
+
+static void
+release_lock(void)
+{
+ unlink(lock_filename);
+}
+
+
+/*
+ * 'handle_sigterm()' - Handle SIGTERM signal.
+ */
+static void
+handle_sigterm(int signum)
+{
+ release_lock();
+ _exit(0);
+}
+
/*
* 'acquire_lock()' - Acquire a lock so we only have a single notifier running.
*/
char *lockfile, /* I - Lock filename buffer */
size_t locksize) /* I - Size of filename buffer */
{
- const char *tmpdir; /* Temporary directory */
+ const char *tmpdir; /* Temporary directory */
+ struct sigaction action; /* POSIX sigaction data */
/*
if ((*fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
return (-1);
- else
- return (0);
+
+ /*
+ * Set a SIGTERM handler to make sure we release the lock if the
+ * scheduler decides to stop us.
+ */
+ memset(&action, 0, sizeof(action));
+ action.sa_handler = handle_sigterm;
+ sigaction(SIGTERM, &action, NULL);
+
+ return (0);
+}
+#else /* !HAVE_DBUS */
+int
+main(void)
+{
+ return (1);
}
+#endif /* HAVE_DBUS */
/*
- * End of "$Id$".
+ * End of "$Id: dbus.c 11500 2014-01-06 22:21:15Z msweet $".
*/