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