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