~ubuntu-branches/ubuntu/utopic/cups/utopic

« back to all changes in this revision

Viewing changes to .pc/avoid_stale_lockfile_in_dbus_notifier.patch/notifier/dbus.c

  • Committer: Package Import Robot
  • Author(s): Didier Raboud, Till Kamppeter, Steve Langasek, Didier Raboud
  • Date: 2014-01-03 18:42:39 UTC
  • mfrom: (99.2.3 sid)
  • Revision ID: package-import@ubuntu.com-20140103184239-85wju2l7weie4dgo
Tags: 1.7.0-1
* New 1.7.0 upstream release

[ Till Kamppeter ]
* Refresh most patches with quilt
* Removed usb-backend-do-not-crash-if-usb-disabled-in-bios and
  cupsd-no-crash-on-avahi-threaded-poll-shutdown patches as they got
  applied upstream
* Removed drop-arch-specifics-from-doc patch as it is not needed
  anymore
* Updated drop_unnecessary_dependencies, manpage-hyphen-minus,
  manpage-translations and ppd-poll-with-client-conf patches manually
  to apply to the new CUPS version
* Added error counting exception from
  usb-backend-do-not-crash-if-usb-disabled-in-bios to
  tests-ignore-warnings
* Install the newly added ippfind utility and its manpage in
  cups-client
* Added pwg.h to libcups2-dev package
* Call dh_auto_clean only if the file Makedefs is present, to avoid a
  FTBFS
* Added color management extensions from Joe Simon's GSoC 2013
  project.
* Patch cups-files.conf to activate CUPS daemon syncing of files when
  closing, so that config files (like printers.conf) do not
  mysteriously disappear (LP: #1157972)
* In the AppArmor profile, allow execution of programs in
  /etc/cups/interfaces/, needed to make CUPS working with queues based
  on System V interface scripts, especially PPD-less queues
  auto-generated by cups-browsed from cups-filters 1.0.41 on.
* Silenced AppArmor noise from udev.conf in syslog (LP: #1229766)

[ Steve Langasek ]
* Add cups-filters (>= 1.0.42) as alternative to foomatic-filters
  (which is deprecated) in package relationships

[ Didier Raboud ]
* Remove Roger Leigh from uploaders on his request with thanks for his
  past work!
* Switch avahi LSB Should-Start dependency to be avahi-daemon; also
  bump package relationship to >= 0.6.31-3~ (Closes: #731608)
* Refresh the manpage translation files
* Move the USB backend quirk rules file to cups-server-common
* Add 38 new 1.7.0 libcups2 symbols
* Mark one C++ libcupsppdc1 symbol as optional as it isn't exported in
  1.7.0 anymore
* Import Fedora patches:
  - to avoid sign-extending CRCs in gz decompression
  - to build with full read-only relocations
  - to fix job history logging (upstream patch)
  - to set the internal default for SyncOnClose to Yes, instead of
    only configuring it to Yes
  - to fix a stringpool corruption issue
  - to prevent USB timeouts causing incorrect print output
* Import Fedora patch updates:
  - to dont-use-dbus-from-two-threads patch so it removes a call to
    avahi_threaded_poll_stop()
  - to avoid_stale_lockfile_in_dbus_notifier patch to call _exit when
    handling SIGTERM
* Move manpage-translations patch at the very end of the patch series
  to have it include all our patches

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * "$Id: dbus.c 3933 2012-10-01 03:01:10Z msweet $"
 
3
 *
 
4
 *   D-Bus notifier for CUPS.
 
5
 *
 
6
 *   Copyright 2008-2012 by Apple Inc.
 
7
 *   Copyright (C) 2011 Red Hat, Inc.
 
8
 *   Copyright (C) 2007 Tim Waugh <twaugh@redhat.com>
 
9
 *   Copyright 1997-2005 by Easy Software Products.
 
10
 *
 
11
 *   These coded instructions, statements, and computer programs are the
 
12
 *   property of Apple Inc. and are protected by Federal copyright
 
13
 *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
 
14
 *   which should have been included with this file.  If this file is
 
15
 *   file is missing or damaged, see the license at "http://www.cups.org/".
 
16
 *
 
17
 * Contents:
 
18
 *
 
19
 *   main()         - Read events and send DBUS notifications.
 
20
 *   acquire_lock() - Acquire a lock so we only have a single notifier running.
 
21
 */
 
22
 
 
23
/*
 
24
 * Include necessary headers...
 
25
 */
 
26
 
 
27
#include <cups/cups.h>
 
28
#include <cups/string-private.h>
 
29
#include <fcntl.h>
 
30
#include <signal.h>
 
31
#include <sys/stat.h>
 
32
#include <sys/types.h>
 
33
#include <unistd.h>
 
34
#include <assert.h>
 
35
#include <locale.h>
 
36
#include <wchar.h>
 
37
 
 
38
#ifdef HAVE_DBUS
 
39
#  include <dbus/dbus.h>
 
40
#  ifdef HAVE_DBUS_MESSAGE_ITER_INIT_APPEND
 
41
#    define dbus_message_append_iter_init dbus_message_iter_init_append
 
42
#    define dbus_message_iter_append_string(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_STRING, v)
 
43
#    define dbus_message_iter_append_uint32(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_UINT32, v)
 
44
#    define dbus_message_iter_append_boolean(i,v) dbus_message_iter_append_basic(i, DBUS_TYPE_BOOLEAN, v)
 
45
#  endif /* HAVE_DBUS_MESSAGE_ITER_INIT_APPEND */
 
46
 
 
47
 
 
48
/*
 
49
 * D-Bus object: org.cups.cupsd.Notifier
 
50
 * D-Bus object path: /org/cups/cupsd/Notifier
 
51
 *
 
52
 * D-Bus interface name: org.cups.cupsd.Notifier
 
53
 *
 
54
 * Signals:
 
55
 *
 
56
 * ServerRestarted(STRING text)
 
57
 * Server has restarted.
 
58
 *
 
59
 * ServerStarted(STRING text)
 
60
 * Server has started.
 
61
 *
 
62
 * ServerStopped(STRING text)
 
63
 * Server has stopped.
 
64
 *
 
65
 * ServerAudit(STRING text)
 
66
 * Security-related event.
 
67
 *
 
68
 * PrinterRestarted(STRING text,
 
69
 *                  STRING printer-uri,
 
70
 *                  STRING printer-name,
 
71
 *                  UINT32 printer-state,
 
72
 *                  STRING printer-state-reasons,
 
73
 *                  BOOLEAN printer-is-accepting-jobs)
 
74
 * Printer has restarted.
 
75
 *
 
76
 * PrinterShutdown(STRING text,
 
77
 *                 STRING printer-uri,
 
78
 *                 STRING printer-name,
 
79
 *                 UINT32 printer-state,
 
80
 *                 STRING printer-state-reasons,
 
81
 *                 BOOLEAN printer-is-accepting-jobs)
 
82
 * Printer has shutdown.
 
83
 *
 
84
 * PrinterStopped(STRING text,
 
85
 *                STRING printer-uri,
 
86
 *                STRING printer-name,
 
87
 *                UINT32 printer-state,
 
88
 *                STRING printer-state-reasons,
 
89
 *                BOOLEAN printer-is-accepting-jobs)
 
90
 * Printer has stopped.
 
91
 *
 
92
 * PrinterStateChanged(STRING text,
 
93
 *                     STRING printer-uri,
 
94
 *                     STRING printer-name,
 
95
 *                     UINT32 printer-state,
 
96
 *                     STRING printer-state-reasons,
 
97
 *                     BOOLEAN printer-is-accepting-jobs)
 
98
 * Printer state has changed.
 
99
 *
 
100
 * PrinterFinishingsChanged(STRING text,
 
101
 *                          STRING printer-uri,
 
102
 *                          STRING printer-name,
 
103
 *                          UINT32 printer-state,
 
104
 *                          STRING printer-state-reasons,
 
105
 *                          BOOLEAN printer-is-accepting-jobs)
 
106
 * Printer's finishings-supported attribute has changed.
 
107
 *
 
108
 * PrinterMediaChanged(STRING text,
 
109
 *                     STRING printer-uri,
 
110
 *                     STRING printer-name,
 
111
 *                     UINT32 printer-state,
 
112
 *                     STRING printer-state-reasons,
 
113
 *                     BOOLEAN printer-is-accepting-jobs)
 
114
 * Printer's media-supported attribute has changed.
 
115
 *
 
116
 * PrinterAdded(STRING text,
 
117
 *              STRING printer-uri,
 
118
 *              STRING printer-name,
 
119
 *              UINT32 printer-state,
 
120
 *              STRING printer-state-reasons,
 
121
 *              BOOLEAN printer-is-accepting-jobs)
 
122
 * Printer has been added.
 
123
 *
 
124
 * PrinterDeleted(STRING text,
 
125
 *                STRING printer-uri,
 
126
 *                STRING printer-name,
 
127
 *                UINT32 printer-state,
 
128
 *                STRING printer-state-reasons,
 
129
 *                BOOLEAN printer-is-accepting-jobs)
 
130
 * Printer has been deleted.
 
131
 *
 
132
 * PrinterModified(STRING text,
 
133
 *                 STRING printer-uri,
 
134
 *                 STRING printer-name,
 
135
 *                 UINT32 printer-state,
 
136
 *                 STRING printer-state-reasons,
 
137
 *                 BOOLEAN printer-is-accepting-jobs)
 
138
 * Printer has been modified.
 
139
 *
 
140
 * text describes the event.
 
141
 * printer-state-reasons is a comma-separated list.
 
142
 * If printer-uri is "" in a Job* signal, the other printer-* parameters
 
143
 * must be ignored.
 
144
 * If the job name is not know, job-name will be "".
 
145
 */
 
146
 
 
147
/*
 
148
 * Constants...
 
149
 */
 
150
 
 
151
enum
 
152
{
 
153
  PARAMS_NONE,
 
154
  PARAMS_PRINTER,
 
155
  PARAMS_JOB
 
156
};
 
157
 
 
158
 
 
159
/*
 
160
 * Local functions...
 
161
 */
 
162
 
 
163
static int              acquire_lock(int *fd, char *lockfile, size_t locksize);
 
164
static const char       *validate_utf8(const char *str);
 
165
 
 
166
 
 
167
/*
 
168
 * 'validate_utf8()' - Convert to valid UTF-8
 
169
 */
 
170
 
 
171
static const char *
 
172
validate_utf8 (const char *str)
 
173
{
 
174
  static char *buffer = NULL;
 
175
  static size_t buflen = 0;
 
176
  char *p;
 
177
  size_t str_len;
 
178
  unsigned int i;
 
179
  mbstate_t instate, outstate;
 
180
 
 
181
  if (str == NULL)
 
182
  {
 
183
    buflen = 0;
 
184
    free (buffer);
 
185
    buffer = NULL;
 
186
    return (NULL);
 
187
  }
 
188
 
 
189
  /* Is it already valid? */
 
190
  if (mbstowcs (NULL, str, 0) != (size_t) -1)
 
191
    return str;
 
192
 
 
193
  /* Make sure our buffer is at least as large as the input string */
 
194
  str_len = strlen (str);
 
195
  if (str_len >= buflen)
 
196
  {
 
197
    if (buffer == NULL)
 
198
      /* Set encoding type to UTF-8 the first time we need to */
 
199
      setlocale (LC_CTYPE, "C.UTF-8");
 
200
 
 
201
    buflen = str_len + 1;
 
202
    buffer = realloc (buffer, buflen);
 
203
  }
 
204
 
 
205
  memset (&instate, '\0', sizeof (mbstate_t));
 
206
  memset (&outstate, '\0', sizeof (mbstate_t));
 
207
  p = buffer;
 
208
  i = 0;
 
209
  while (i < str_len)
 
210
  {
 
211
    wchar_t wc;
 
212
    size_t used, written;
 
213
    mbstate_t orig_instate = instate;
 
214
    used = mbrtowc (&wc, str + i, str_len - i, &instate);
 
215
    switch (used)
 
216
    {
 
217
    case (size_t) -2:
 
218
    case (size_t) -1:
 
219
      wc = L'?'; /* so replacement is never longer than original char */
 
220
      instate = orig_instate;
 
221
      /* fallthru */
 
222
    case 0:
 
223
      used = 1;
 
224
    }
 
225
 
 
226
    written = wcrtomb (p, wc, &outstate);
 
227
    if (written != -1)
 
228
    {
 
229
      p += written;
 
230
      assert (p - buffer < buflen);
 
231
    }
 
232
 
 
233
    i += used;
 
234
  }
 
235
 
 
236
  *p = '\0';
 
237
  return buffer;
 
238
}
 
239
 
 
240
/*
 
241
 * 'main()' - Read events and send DBUS notifications.
 
242
 */
 
243
 
 
244
int                                     /* O - Exit status */
 
245
main(int  argc,                         /* I - Number of command-line args */
 
246
     char *argv[])                      /* I - Command-line arguments */
 
247
{
 
248
  ipp_t                 *msg;           /* Event message from scheduler */
 
249
  ipp_state_t           state;          /* IPP event state */
 
250
  struct sigaction      action;         /* POSIX sigaction data */
 
251
  DBusConnection        *con = NULL;    /* Connection to DBUS server */
 
252
  DBusError             error;          /* Error, if any */
 
253
  DBusMessage           *message;       /* Message to send */
 
254
  DBusMessageIter       iter;           /* Iterator for message data */
 
255
  int                   lock_fd = -1;   /* Lock file descriptor */
 
256
  char                  lock_filename[1024];
 
257
                                        /* Lock filename */
 
258
 
 
259
 
 
260
 /*
 
261
  * Don't buffer stderr...
 
262
  */
 
263
 
 
264
  setbuf(stderr, NULL);
 
265
 
 
266
 /*
 
267
  * Ignore SIGPIPE signals...
 
268
  */
 
269
 
 
270
  memset(&action, 0, sizeof(action));
 
271
  action.sa_handler = SIG_IGN;
 
272
  sigaction(SIGPIPE, &action, NULL);
 
273
 
 
274
 /*
 
275
  * Validate command-line options...
 
276
  */
 
277
 
 
278
  if (argc != 3)
 
279
  {
 
280
    fputs("Usage: dbus dbus:/// notify-user-data\n", stderr);
 
281
    return (1);
 
282
  }
 
283
 
 
284
  if (strncmp(argv[1], "dbus:", 5))
 
285
  {
 
286
    fprintf(stderr, "ERROR: Bad URI \"%s\"!\n", argv[1]);
 
287
    return (1);
 
288
  }
 
289
 
 
290
 /*
 
291
  * Loop forever until we run out of events...
 
292
  */
 
293
 
 
294
  for (;;)
 
295
  {
 
296
    ipp_attribute_t     *attr;          /* Current attribute */
 
297
    const char          *event;         /* Event name */
 
298
    const char          *signame = NULL;/* DBUS signal name */
 
299
    char                *printer_reasons = NULL;
 
300
                                        /* Printer reasons string */
 
301
    char                *job_reasons = NULL;
 
302
                                        /* Job reasons string */
 
303
    const char          *nul = "";      /* Empty string value */
 
304
    int                 no = 0;         /* Boolean "no" value */
 
305
    int                 params = PARAMS_NONE;
 
306
                                        /* What parameters to include? */
 
307
    const char          *val;
 
308
 
 
309
 
 
310
   /*
 
311
    * Get the next event...
 
312
    */
 
313
 
 
314
    msg = ippNew();
 
315
    while ((state = ippReadFile(0, msg)) != IPP_DATA)
 
316
    {
 
317
      if (state <= IPP_IDLE)
 
318
        break;
 
319
    }
 
320
 
 
321
    fprintf(stderr, "DEBUG: state=%d\n", state);
 
322
 
 
323
    if (state == IPP_ERROR)
 
324
      fputs("DEBUG: ippReadFile() returned IPP_ERROR!\n", stderr);
 
325
 
 
326
    if (state <= IPP_IDLE)
 
327
    {
 
328
     /*
 
329
      * Out of messages, free memory and then exit...
 
330
      */
 
331
 
 
332
      ippDelete(msg);
 
333
      break;
 
334
    }
 
335
 
 
336
   /*
 
337
    * Verify connection to DBUS server...
 
338
    */
 
339
 
 
340
    if (con && !dbus_connection_get_is_connected(con))
 
341
    {
 
342
      dbus_connection_unref(con);
 
343
      con = NULL;
 
344
    }
 
345
 
 
346
    if (!con)
 
347
    {
 
348
      dbus_error_init(&error);
 
349
 
 
350
      con = dbus_bus_get(DBUS_BUS_SYSTEM, &error);
 
351
      if (!con)
 
352
        dbus_error_free(&error);
 
353
      else
 
354
        fputs("DEBUG: Connected to D-BUS\n", stderr);
 
355
    }
 
356
 
 
357
    if (!con)
 
358
      continue;
 
359
 
 
360
    if (lock_fd == -1 &&
 
361
        acquire_lock(&lock_fd, lock_filename, sizeof(lock_filename)))
 
362
      continue;
 
363
 
 
364
    attr = ippFindAttribute(msg, "notify-subscribed-event",
 
365
                            IPP_TAG_KEYWORD);
 
366
    if (!attr)
 
367
      continue;
 
368
 
 
369
    event = ippGetString(attr, 0, NULL);
 
370
    if (!strncmp(event, "server-", 7))
 
371
    {
 
372
      const char *word2 = event + 7;    /* Second word */
 
373
 
 
374
      if (!strcmp(word2, "restarted"))
 
375
        signame = "ServerRestarted";
 
376
      else if (!strcmp(word2, "started"))
 
377
        signame = "ServerStarted";
 
378
      else if (!strcmp(word2, "stopped"))
 
379
        signame = "ServerStopped";
 
380
      else if (!strcmp(word2, "audit"))
 
381
        signame = "ServerAudit";
 
382
      else
 
383
        continue;
 
384
    }
 
385
    else if (!strncmp(event, "printer-", 8))
 
386
    {
 
387
      const char *word2 = event + 8;    /* Second word */
 
388
 
 
389
      params = PARAMS_PRINTER;
 
390
      if (!strcmp(word2, "restarted"))
 
391
        signame = "PrinterRestarted";
 
392
      else if (!strcmp(word2, "shutdown"))
 
393
        signame = "PrinterShutdown";
 
394
      else if (!strcmp(word2, "stopped"))
 
395
        signame = "PrinterStopped";
 
396
      else if (!strcmp(word2, "state-changed"))
 
397
        signame = "PrinterStateChanged";
 
398
      else if (!strcmp(word2, "finishings-changed"))
 
399
        signame = "PrinterFinishingsChanged";
 
400
      else if (!strcmp(word2, "media-changed"))
 
401
        signame = "PrinterMediaChanged";
 
402
      else if (!strcmp(word2, "added"))
 
403
        signame = "PrinterAdded";
 
404
      else if (!strcmp(word2, "deleted"))
 
405
        signame = "PrinterDeleted";
 
406
      else if (!strcmp(word2, "modified"))
 
407
        signame = "PrinterModified";
 
408
      else
 
409
        continue;
 
410
    }
 
411
    else if (!strncmp(event, "job-", 4))
 
412
    {
 
413
      const char *word2 = event + 4;    /* Second word */
 
414
 
 
415
      params = PARAMS_JOB;
 
416
      if (!strcmp(word2, "state-changed"))
 
417
        signame = "JobState";
 
418
      else if (!strcmp(word2, "created"))
 
419
        signame = "JobCreated";
 
420
      else if (!strcmp(word2, "completed"))
 
421
        signame = "JobCompleted";
 
422
      else if (!strcmp(word2, "stopped"))
 
423
        signame = "JobStopped";
 
424
      else if (!strcmp(word2, "config-changed"))
 
425
        signame = "JobConfigChanged";
 
426
      else if (!strcmp(word2, "progress"))
 
427
        signame = "JobProgress";
 
428
      else
 
429
        continue;
 
430
    }
 
431
    else
 
432
      continue;
 
433
 
 
434
    /*
 
435
     * Create and send the new message...
 
436
     */
 
437
 
 
438
    fprintf(stderr, "DEBUG: %s\n", signame);
 
439
    message = dbus_message_new_signal("/org/cups/cupsd/Notifier",
 
440
                                      "org.cups.cupsd.Notifier",
 
441
                                      signame);
 
442
 
 
443
    dbus_message_append_iter_init(message, &iter);
 
444
    attr = ippFindAttribute(msg, "notify-text", IPP_TAG_TEXT);
 
445
    if (attr)
 
446
    {
 
447
      const char *val = validate_utf8 (ippGetString(attr, 0, NULL));
 
448
      if (!dbus_message_iter_append_string(&iter, &val))
 
449
        goto bail;
 
450
    }
 
451
    else
 
452
      goto bail;
 
453
 
 
454
    if (params >= PARAMS_PRINTER)
 
455
    {
 
456
      char      *p;                     /* Pointer into printer_reasons */
 
457
      size_t    reasons_length;         /* Required size of printer_reasons */
 
458
      int       i;                      /* Looping var */
 
459
      int       have_printer_params = 1;/* Do we have printer URI? */
 
460
 
 
461
      /* STRING printer-uri or "" */
 
462
      attr = ippFindAttribute(msg, "notify-printer-uri", IPP_TAG_URI);
 
463
      if (attr)
 
464
      {
 
465
        const char *val = ippGetString(attr, 0, NULL);
 
466
        if (!dbus_message_iter_append_string(&iter, &val))
 
467
          goto bail;
 
468
      }
 
469
      else
 
470
      {
 
471
        have_printer_params = 0;
 
472
        dbus_message_iter_append_string(&iter, &nul);
 
473
      }
 
474
 
 
475
      /* STRING printer-name */
 
476
      if (have_printer_params)
 
477
      {
 
478
        attr = ippFindAttribute(msg, "printer-name", IPP_TAG_NAME);
 
479
        if (attr)
 
480
        {
 
481
          const char *val = ippGetString(attr, 0, NULL);
 
482
          if (!dbus_message_iter_append_string(&iter, &val))
 
483
            goto bail;
 
484
        }
 
485
        else
 
486
          goto bail;
 
487
      }
 
488
      else
 
489
        dbus_message_iter_append_string(&iter, &nul);
 
490
 
 
491
      /* UINT32 printer-state */
 
492
      if (have_printer_params)
 
493
      {
 
494
        attr = ippFindAttribute(msg, "printer-state", IPP_TAG_ENUM);
 
495
        if (attr)
 
496
        {
 
497
          dbus_uint32_t val = ippGetInteger(attr, 0);
 
498
          dbus_message_iter_append_uint32(&iter, &val);
 
499
        }
 
500
        else
 
501
          goto bail;
 
502
      }
 
503
      else
 
504
        dbus_message_iter_append_uint32(&iter, &no);
 
505
 
 
506
      /* STRING printer-state-reasons */
 
507
      if (have_printer_params)
 
508
      {
 
509
        attr = ippFindAttribute(msg, "printer-state-reasons",
 
510
                                IPP_TAG_KEYWORD);
 
511
        if (attr)
 
512
        {
 
513
          int num_values = ippGetCount(attr);
 
514
          for (reasons_length = 0, i = 0; i < num_values; i++)
 
515
            /* All need commas except the last, which needs a nul byte. */
 
516
            reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
 
517
          printer_reasons = malloc(reasons_length);
 
518
          if (!printer_reasons)
 
519
            goto bail;
 
520
          p = printer_reasons;
 
521
          for (i = 0; i < num_values; i++)
 
522
          {
 
523
            if (i)
 
524
              *p++ = ',';
 
525
 
 
526
            strlcpy(p, ippGetString(attr, i, NULL),
 
527
                    reasons_length - (p - printer_reasons));
 
528
            p += strlen(p);
 
529
          }
 
530
          if (!dbus_message_iter_append_string(&iter, &printer_reasons))
 
531
            goto bail;
 
532
        }
 
533
        else
 
534
          goto bail;
 
535
      }
 
536
      else
 
537
        dbus_message_iter_append_string(&iter, &nul);
 
538
 
 
539
      /* BOOL printer-is-accepting-jobs */
 
540
      if (have_printer_params)
 
541
      {
 
542
        attr = ippFindAttribute(msg, "printer-is-accepting-jobs",
 
543
                                IPP_TAG_BOOLEAN);
 
544
        if (attr)
 
545
        {
 
546
          dbus_bool_t val = ippGetBoolean(attr, 0);
 
547
          dbus_message_iter_append_boolean(&iter, &val);
 
548
        }
 
549
        else
 
550
          goto bail;
 
551
      }
 
552
      else
 
553
        dbus_message_iter_append_boolean(&iter, &no);
 
554
    }
 
555
 
 
556
    if (params >= PARAMS_JOB)
 
557
    {
 
558
      char      *p;                     /* Pointer into job_reasons */
 
559
      size_t    reasons_length;         /* Required size of job_reasons */
 
560
      int       i;                      /* Looping var */
 
561
 
 
562
      /* UINT32 job-id */
 
563
      attr = ippFindAttribute(msg, "notify-job-id", IPP_TAG_INTEGER);
 
564
      if (attr)
 
565
      {
 
566
        dbus_uint32_t val = ippGetInteger(attr, 0);
 
567
        dbus_message_iter_append_uint32(&iter, &val);
 
568
      }
 
569
      else
 
570
        goto bail;
 
571
 
 
572
      /* UINT32 job-state */
 
573
      attr = ippFindAttribute(msg, "job-state", IPP_TAG_ENUM);
 
574
      if (attr)
 
575
      {
 
576
        dbus_uint32_t val = ippGetInteger(attr, 0);
 
577
        dbus_message_iter_append_uint32(&iter, &val);
 
578
      }
 
579
      else
 
580
        goto bail;
 
581
 
 
582
      /* STRING job-state-reasons */
 
583
      attr = ippFindAttribute(msg, "job-state-reasons", IPP_TAG_KEYWORD);
 
584
      if (attr)
 
585
      {
 
586
        int num_values = ippGetCount(attr);
 
587
        for (reasons_length = 0, i = 0; i < num_values; i++)
 
588
          /* All need commas except the last, which needs a nul byte. */
 
589
          reasons_length += 1 + strlen(ippGetString(attr, i, NULL));
 
590
        job_reasons = malloc(reasons_length);
 
591
        if (!job_reasons)
 
592
          goto bail;
 
593
        p = job_reasons;
 
594
        for (i = 0; i < num_values; i++)
 
595
        {
 
596
          if (i)
 
597
            *p++ = ',';
 
598
 
 
599
          strlcpy(p, ippGetString(attr, i, NULL),
 
600
                  reasons_length - (p - job_reasons));
 
601
          p += strlen(p);
 
602
        }
 
603
        if (!dbus_message_iter_append_string(&iter, &job_reasons))
 
604
          goto bail;
 
605
      }
 
606
      else
 
607
        goto bail;
 
608
 
 
609
      /* STRING job-name or "" */
 
610
      attr = ippFindAttribute(msg, "job-name", IPP_TAG_NAME);
 
611
      if (attr)
 
612
      {
 
613
        const char *val = validate_utf8(ippGetString(attr, 0, NULL));
 
614
        if (!dbus_message_iter_append_string(&iter, &val))
 
615
          goto bail;
 
616
      }
 
617
      else
 
618
        dbus_message_iter_append_string(&iter, &nul);
 
619
 
 
620
      /* UINT32 job-impressions-completed */
 
621
      attr = ippFindAttribute(msg, "job-impressions-completed",
 
622
                              IPP_TAG_INTEGER);
 
623
      if (attr)
 
624
      {
 
625
        dbus_uint32_t val = ippGetInteger(attr, 0);
 
626
        dbus_message_iter_append_uint32(&iter, &val);
 
627
      }
 
628
      else
 
629
        goto bail;
 
630
    }
 
631
 
 
632
    dbus_connection_send(con, message, NULL);
 
633
    dbus_connection_flush(con);
 
634
 
 
635
   /*
 
636
    * Cleanup...
 
637
    */
 
638
 
 
639
    bail:
 
640
 
 
641
    dbus_message_unref(message);
 
642
 
 
643
    if (printer_reasons)
 
644
      free(printer_reasons);
 
645
 
 
646
    if (job_reasons)
 
647
      free(job_reasons);
 
648
 
 
649
    ippDelete(msg);
 
650
  }
 
651
 
 
652
 /*
 
653
  * Remove lock file...
 
654
  */
 
655
 
 
656
  if (lock_fd >= 0)
 
657
  {
 
658
    close(lock_fd);
 
659
    unlink(lock_filename);
 
660
  }
 
661
 
 
662
  return (0);
 
663
}
 
664
 
 
665
 
 
666
/*
 
667
 * 'acquire_lock()' - Acquire a lock so we only have a single notifier running.
 
668
 */
 
669
 
 
670
static int                              /* O - 0 on success, -1 on failure */
 
671
acquire_lock(int    *fd,                /* O - Lock file descriptor */
 
672
             char   *lockfile,          /* I - Lock filename buffer */
 
673
             size_t locksize)           /* I - Size of filename buffer */
 
674
{
 
675
  const char    *tmpdir;                /* Temporary directory */
 
676
 
 
677
 
 
678
 /*
 
679
  * Figure out where to put the lock file...
 
680
  */
 
681
 
 
682
  if ((tmpdir = getenv("TMPDIR")) == NULL)
 
683
    tmpdir = "/tmp";
 
684
 
 
685
  snprintf(lockfile, locksize, "%s/cups-dbus-notifier-lockfile", tmpdir);
 
686
 
 
687
 /*
 
688
  * Create the lock file and fail if it already exists...
 
689
  */
 
690
 
 
691
  if ((*fd = open(lockfile, O_RDWR | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR)) < 0)
 
692
    return (-1);
 
693
  else
 
694
    return (0);
 
695
}
 
696
#else /* !HAVE_DBUS */
 
697
int
 
698
main(void)
 
699
{
 
700
  return (1);
 
701
}
 
702
#endif /* HAVE_DBUS */
 
703
 
 
704
 
 
705
/*
 
706
 * End of "$Id: dbus.c 3933 2012-10-01 03:01:10Z msweet $".
 
707
 */