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

« back to all changes in this revision

Viewing changes to scheduler/avahi.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$"
 
3
 *
 
4
 *   Avahi poll implementation for the CUPS scheduler.
 
5
 *
 
6
 *   Copyright (C) 2010, 2011 Red Hat, Inc.
 
7
 *   Authors:
 
8
 *    Tim Waugh <twaugh@redhat.com>
 
9
 *
 
10
 *   Redistribution and use in source and binary forms, with or without
 
11
 *   modification, are permitted provided that the following conditions
 
12
 *   are met:
 
13
 *
 
14
 *   Redistributions of source code must retain the above copyright
 
15
 *   notice, this list of conditions and the following disclaimer.
 
16
 *
 
17
 *   Redistributions in binary form must reproduce the above copyright
 
18
 *   notice, this list of conditions and the following disclaimer in the
 
19
 *   documentation and/or other materials provided with the distribution.
 
20
 *
 
21
 *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 
22
 *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 
23
 *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 
24
 *   FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
 
25
 *   COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 
26
 *   INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 
27
 *   (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 
28
 *   SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 
29
 *   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 
30
 *   STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 
31
 *   ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 
32
 *   OF THE POSSIBILITY OF SUCH DAMAGE.
 
33
 *
 
34
 * Contents:
 
35
 *
 
36
 *   watch_read_cb         - Read callback for file descriptor
 
37
 *   watch_write_cb        - Write callback for file descriptor
 
38
 *   watched_fd_add_select() - Call cupsdAddSelect() as needed
 
39
 *   watch_new()           - Create a new file descriptor watch
 
40
 *   watch_free()          - Free a file descriptor watch
 
41
 *   watch_update()        - Update watched events for a file descriptor
 
42
 *   watch_get_events()    - Get events that happened for a file descriptor
 
43
 *   timeout_cb()          - Run a timed Avahi callback
 
44
 *   timeout_new()         - Set a wakeup time
 
45
 *   timeout_update()      - Update the expiration time for a timeout
 
46
 *   timeout_free()        - Free a timeout
 
47
 *   compare_watched_fds() - Compare watched file descriptors for array sorting
 
48
 *   avahi_cups_poll_new() - Create a new Avahi main loop object for CUPS
 
49
 *   avahi_cups_poll_free() - Free an Avahi main loop object for CUPS
 
50
 *   avahi_cups_poll_get() - Get the abstract poll API structure
 
51
 */
 
52
 
 
53
#include <config.h>
 
54
 
 
55
#ifdef HAVE_AVAHI /* Applies to entire file... */
 
56
 
 
57
/*
 
58
 * Include necessary headers...
 
59
 */
 
60
 
 
61
#include "cupsd.h"
 
62
 
 
63
#if defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
 
64
#  include <malloc.h>
 
65
#endif /* HAVE_MALLOC_H && HAVE_MALLINFO */
 
66
 
 
67
#ifdef HAVE_AVAHI
 
68
#  include <avahi-common/timeval.h>
 
69
#endif /* HAVE_AVAHI */
 
70
 
 
71
 
 
72
typedef struct
 
73
{
 
74
  AvahiCupsPoll *cups_poll;
 
75
 
 
76
  int fd;
 
77
  AvahiWatchEvent occurred;
 
78
  cups_array_t *watches;
 
79
} cupsd_watched_fd_t;
 
80
 
 
81
struct AvahiWatch
 
82
{
 
83
  cupsd_watched_fd_t *watched_fd;
 
84
 
 
85
  AvahiWatchEvent events;
 
86
  AvahiWatchCallback callback;
 
87
  void *userdata;
 
88
};
 
89
 
 
90
struct AvahiTimeout
 
91
{
 
92
  AvahiCupsPoll *cups_poll;
 
93
  AvahiTimeoutCallback callback;
 
94
  void *userdata;
 
95
  cupsd_timeout_t *cupsd_timeout;
 
96
};
 
97
 
 
98
/*
 
99
 * Local functions...
 
100
 */
 
101
 
 
102
static AvahiWatch *     watch_new(const AvahiPoll *api,
 
103
                                  int fd,
 
104
                                  AvahiWatchEvent events,
 
105
                                  AvahiWatchCallback callback,
 
106
                                  void *userdata);
 
107
static void             watch_free(AvahiWatch *watch);
 
108
static void             watch_update(AvahiWatch *watch,
 
109
                                     AvahiWatchEvent events);
 
110
static AvahiWatchEvent  watch_get_events(AvahiWatch *watch);
 
111
 
 
112
 
 
113
/*
 
114
 * 'watch_read_cb' - Read callback for file descriptor
 
115
 */
 
116
 
 
117
static void
 
118
watch_read_cb (void *userdata)
 
119
{
 
120
  AvahiWatch *watch;
 
121
  cupsd_watched_fd_t *watched_fd = userdata;
 
122
  watched_fd->occurred |= AVAHI_WATCH_IN;
 
123
  for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
 
124
       watch;
 
125
       watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
 
126
  {
 
127
    if (watch->events & watched_fd->occurred)
 
128
    {
 
129
      (watch->callback) (watch, watched_fd->fd,
 
130
                         AVAHI_WATCH_IN, watch->userdata);
 
131
      watched_fd->occurred &= ~AVAHI_WATCH_IN;
 
132
      break;
 
133
    }
 
134
  }
 
135
}
 
136
 
 
137
 
 
138
/*
 
139
 * 'watch_write_cb' - Write callback for file descriptor
 
140
 */
 
141
 
 
142
static void
 
143
watch_write_cb (void *userdata)
 
144
{
 
145
  AvahiWatch *watch;
 
146
  cupsd_watched_fd_t *watched_fd = userdata;
 
147
  watched_fd->occurred |= AVAHI_WATCH_OUT;
 
148
  for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
 
149
       watch;
 
150
       watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
 
151
  {
 
152
    if (watch->events & watched_fd->occurred)
 
153
    {
 
154
      (watch->callback) (watch, watched_fd->fd,
 
155
                         AVAHI_WATCH_OUT, watch->userdata);
 
156
      watched_fd->occurred &= ~AVAHI_WATCH_OUT;
 
157
      break;
 
158
    }
 
159
  }
 
160
}
 
161
 
 
162
 
 
163
/*
 
164
 * 'watched_fd_add_select' - Call cupsdAddSelect() as needed
 
165
 */
 
166
 
 
167
static int                                              /* O - Watches? */
 
168
watched_fd_add_select (cupsd_watched_fd_t *watched_fd)
 
169
{
 
170
  AvahiWatch *watch;
 
171
  cupsd_selfunc_t read_cb = NULL, write_cb = NULL;
 
172
  int any_watches = 0;
 
173
 
 
174
  for (watch = (AvahiWatch *)cupsArrayFirst(watched_fd->watches);
 
175
       watch;
 
176
       watch = (AvahiWatch *)cupsArrayNext(watched_fd->watches))
 
177
  {
 
178
    any_watches = 1;
 
179
    if (watch->events & (AVAHI_WATCH_IN |
 
180
                             AVAHI_WATCH_ERR |
 
181
                             AVAHI_WATCH_HUP))
 
182
    {
 
183
      read_cb = (cupsd_selfunc_t)watch_read_cb;
 
184
      if (write_cb != NULL)
 
185
        break;
 
186
    }
 
187
 
 
188
    if (watch->events & AVAHI_WATCH_OUT)
 
189
    {
 
190
      write_cb = (cupsd_selfunc_t)watch_write_cb;
 
191
      if (read_cb != NULL)
 
192
        break;
 
193
    }
 
194
  }
 
195
 
 
196
  if (read_cb || write_cb)
 
197
    cupsdAddSelect (watched_fd->fd, read_cb, write_cb, watched_fd);
 
198
  else
 
199
    cupsdRemoveSelect (watched_fd->fd);
 
200
 
 
201
  return (any_watches);
 
202
}
 
203
 
 
204
/*
 
205
 * 'watch_new' - Create a new file descriptor watch
 
206
 */
 
207
 
 
208
static AvahiWatch *
 
209
watch_new (const AvahiPoll *api,
 
210
           int fd,
 
211
           AvahiWatchEvent events,
 
212
           AvahiWatchCallback callback,
 
213
           void *userdata)
 
214
{
 
215
  cupsd_watched_fd_t key, *watched_fd;
 
216
  AvahiCupsPoll *cups_poll = api->userdata;
 
217
  AvahiWatch *watch = malloc(sizeof(AvahiWatch));
 
218
  if (watch == NULL)
 
219
    return (NULL);
 
220
 
 
221
  watch->events = events;
 
222
  watch->callback = callback;
 
223
  watch->userdata = userdata;
 
224
 
 
225
  key.fd = fd;
 
226
  watched_fd = cupsArrayFind (cups_poll->watched_fds, &key);
 
227
  if (watched_fd == NULL)
 
228
  {
 
229
    watched_fd = malloc(sizeof(cupsd_watched_fd_t));
 
230
    if (watched_fd == NULL)
 
231
    {
 
232
      free (watch);
 
233
      return (NULL);
 
234
    }
 
235
 
 
236
    watched_fd->fd = fd;
 
237
    watched_fd->occurred = 0;
 
238
    watched_fd->cups_poll = cups_poll;
 
239
    watched_fd->watches = cupsArrayNew (NULL, NULL);
 
240
    cupsArrayAdd (cups_poll->watched_fds, watched_fd);
 
241
  }
 
242
 
 
243
  watch->watched_fd = watched_fd;
 
244
  cupsArrayAdd(watched_fd->watches, watch);
 
245
  watched_fd_add_select (watched_fd);
 
246
  return (watch);
 
247
}
 
248
 
 
249
 
 
250
/*
 
251
 * 'watch_free' - Free a file descriptor watch
 
252
 */
 
253
 
 
254
static void
 
255
watch_free (AvahiWatch *watch)
 
256
{
 
257
  cupsd_watched_fd_t *watched_fd = watch->watched_fd;
 
258
  AvahiCupsPoll *cups_poll = watched_fd->cups_poll;
 
259
 
 
260
  cupsArrayRemove (watched_fd->watches, watch);
 
261
  free (watch);
 
262
 
 
263
  if (!watched_fd_add_select (watched_fd))
 
264
  {
 
265
    /* No more watches */
 
266
    cupsArrayRemove (cups_poll->watched_fds, watched_fd);
 
267
    free (watched_fd);
 
268
  }
 
269
}
 
270
 
 
271
 
 
272
/*
 
273
 * 'watch_update' - Update watched events for a file descriptor
 
274
 */
 
275
 
 
276
static void
 
277
watch_update (AvahiWatch *watch,
 
278
              AvahiWatchEvent events)
 
279
{
 
280
  watch->events = events;
 
281
  watched_fd_add_select (watch->watched_fd);
 
282
}
 
283
 
 
284
 
 
285
/*
 
286
 * 'watch_get_events' - Get events that happened for a file descriptor
 
287
 */
 
288
 
 
289
static AvahiWatchEvent
 
290
watch_get_events (AvahiWatch *watch)
 
291
{
 
292
  return (watch->watched_fd->occurred);
 
293
}
 
294
 
 
295
 
 
296
/*
 
297
 * 'timeout_cb()' - Run a timed Avahi callback
 
298
 */
 
299
 
 
300
static void
 
301
timeout_cb (cupsd_timeout_t *cupsd_timeout, void *userdata)
 
302
{
 
303
  AvahiTimeout *timeout = userdata;
 
304
  (timeout->callback) (timeout, timeout->userdata);
 
305
}
 
306
 
 
307
 
 
308
/*
 
309
 * 'timeout_new' - Set a wakeup time
 
310
 */
 
311
 
 
312
static AvahiTimeout *
 
313
timeout_new (const AvahiPoll *api,
 
314
             const struct timeval *tv,
 
315
             AvahiTimeoutCallback callback,
 
316
             void *userdata)
 
317
{
 
318
  AvahiTimeout *timeout;
 
319
  AvahiCupsPoll *cups_poll = api->userdata;
 
320
 
 
321
  timeout = malloc(sizeof(AvahiTimeout));
 
322
  if (timeout == NULL)
 
323
    return (NULL);
 
324
 
 
325
  timeout->cups_poll = cups_poll;
 
326
  timeout->callback = callback;
 
327
  timeout->userdata = userdata;
 
328
  timeout->cupsd_timeout = cupsdAddTimeout (tv,
 
329
                                            (cupsd_timeoutfunc_t)timeout_cb,
 
330
                                            timeout);
 
331
  cupsArrayAdd (cups_poll->timeouts, timeout);
 
332
  return (timeout);
 
333
}
 
334
 
 
335
 
 
336
/*
 
337
 * 'timeout_update' - Update the expiration time for a timeout
 
338
 */
 
339
 
 
340
static void
 
341
timeout_update (AvahiTimeout *timeout,
 
342
                const struct timeval *tv)
 
343
{
 
344
  cupsdUpdateTimeout (timeout->cupsd_timeout, tv);
 
345
}
 
346
 
 
347
 
 
348
/*
 
349
 * ' timeout_free' - Free a timeout
 
350
 */
 
351
 
 
352
static void
 
353
timeout_free (AvahiTimeout *timeout)
 
354
{
 
355
  cupsArrayRemove (timeout->cups_poll->timeouts, timeout);
 
356
  cupsdRemoveTimeout (timeout->cupsd_timeout);
 
357
  free (timeout);
 
358
}
 
359
 
 
360
 
 
361
/*
 
362
 * 'compare_watched_fds' - Compare watched file descriptors for array sorting
 
363
 */
 
364
static int
 
365
compare_watched_fds(cupsd_watched_fd_t *p0,
 
366
                    cupsd_watched_fd_t *p1)
 
367
{
 
368
  /*
 
369
   * Compare by fd (no two elements have the same fd)
 
370
   */
 
371
 
 
372
  if (p0->fd == p1->fd)
 
373
    return 0;
 
374
 
 
375
  return (p0->fd < p1->fd ? -1 : 1);
 
376
}
 
377
 
 
378
 
 
379
/*
 
380
 * 'avahi_cups_poll_new' - Create a new Avahi main loop object for CUPS
 
381
 */
 
382
 
 
383
AvahiCupsPoll *
 
384
avahi_cups_poll_new (void)
 
385
{
 
386
  AvahiCupsPoll *cups_poll = malloc(sizeof(AvahiCupsPoll));
 
387
  if (cups_poll == NULL)
 
388
    return (NULL);
 
389
 
 
390
  cups_poll->watched_fds = cupsArrayNew ((cups_array_func_t)compare_watched_fds,
 
391
                                         NULL);
 
392
  cups_poll->timeouts = cupsArrayNew (NULL, NULL);
 
393
 
 
394
  cups_poll->api.userdata = cups_poll;
 
395
  cups_poll->api.watch_new = watch_new;
 
396
  cups_poll->api.watch_free = watch_free;
 
397
  cups_poll->api.watch_update = watch_update;
 
398
  cups_poll->api.watch_get_events = watch_get_events;
 
399
 
 
400
  cups_poll->api.timeout_new = timeout_new;
 
401
  cups_poll->api.timeout_update = timeout_update;
 
402
  cups_poll->api.timeout_free = timeout_free;
 
403
 
 
404
  return (cups_poll);
 
405
}
 
406
 
 
407
 
 
408
/*
 
409
 * 'avahi_cups_poll_free' - Free an Avahi main loop object for CUPS
 
410
 */
 
411
void
 
412
avahi_cups_poll_free (AvahiCupsPoll *cups_poll)
 
413
{
 
414
  cupsd_watched_fd_t *watched_fd;
 
415
 
 
416
  for (watched_fd = (cupsd_watched_fd_t*)cupsArrayFirst(cups_poll->watched_fds);
 
417
       watched_fd;
 
418
       watched_fd = (cupsd_watched_fd_t*)cupsArrayNext(cups_poll->watched_fds))
 
419
    cupsArrayClear (watched_fd->watches);
 
420
 
 
421
  cupsArrayClear (cups_poll->watched_fds);
 
422
  cupsArrayClear (cups_poll->timeouts);
 
423
}
 
424
 
 
425
 
 
426
/*
 
427
 * 'avahi_cups_poll_get' - Get the abstract poll API structure
 
428
 */
 
429
 
 
430
const AvahiPoll *
 
431
avahi_cups_poll_get (AvahiCupsPoll *cups_poll)
 
432
{
 
433
  return (&cups_poll->api);
 
434
}
 
435
 
 
436
 
 
437
#endif /* HAVE_AVAHI ... from top of file */
 
438
 
 
439
/*
 
440
 * End of "$Id$".
 
441
 */