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