Merge commit 'upstream/2.0.4'
Michael Meskes
14 years ago
0 | %changelog | |
0 | * Thu Apr 15 2010 Ted Felix <http://www.tedfelix.com> | |
1 | - 2.0.4 release | |
2 | - Replaced all the mandb code in the makefile with a comment. (Makefile) | |
3 | (Ted Felix) | |
4 | - Revamped logging. (acpid.c event.c inotify_handler.c input_layer.c | |
5 | netlink.c proc.c sock.c) (Ted Felix) | |
6 | - Removed CR's (\r) from files. (Changelog connection_list.c sock.c) | |
7 | (Ted Felix) | |
8 | - Cleaned up the samples directory a bit. Also added powerbtn samples | |
9 | taken from Debian. (samples/*) (Ted Felix) | |
10 | - Removed the %changelog token from the top of the Changelog. This | |
11 | appears to be a Red Hat-ism. (Changelog) (Ted Felix) | |
12 | ||
1 | 13 | * Mon Mar 15 2010 Ted Felix <http://www.tedfelix.com> |
2 | 14 | - 2.0.3 release |
3 | 15 | - Fixed problem in makefile with mandb line when DESTDIR is not empty. |
21 | 33 | * Fri Jan 15 2010 Ted Felix <http://www.tedfelix.com> |
22 | 34 | - 2.0.1 release |
23 | 35 | - Makefile improvements for packagers. (Makefile) (Robby Workman) |
24 | * Use DESTDIR instead of INSTPREFIX | |
25 | * Allow custom compiler optimizations | |
26 | * Allow alternative prefix | |
27 | * Allow custom manpage directory | |
28 | * Add DOCDIR and install docs | |
29 | * Remove reference to "mandb -q" - this doesn't exist everywhere | |
30 | ||
36 | * Use DESTDIR instead of INSTPREFIX | |
37 | * Allow custom compiler optimizations | |
38 | * Allow alternative prefix | |
39 | * Allow custom manpage directory | |
40 | * Add DOCDIR and install docs | |
41 | * Remove reference to "mandb -q" - this doesn't exist everywhere | |
42 | ||
31 | 43 | After this patch, packagers can do e.g.: |
32 | ||
33 | make install \ | |
34 | OPT="-O3" \ | |
35 | PREFIX=/opt \ | |
36 | MANDIR=/opt/man \ | |
37 | DOCDIR=/opt/doc/apcid \ | |
44 | ||
45 | make install \ | |
46 | OPT="-O3" \ | |
47 | PREFIX=/opt \ | |
48 | MANDIR=/opt/man \ | |
49 | DOCDIR=/opt/doc/apcid \ | |
38 | 50 | DESTDIR=/tmp/package |
39 | ||
51 | ||
40 | 52 | - run-parts(8) naming convention for configuration files. (event.c |
41 | 53 | acpid.8) (Debian) |
42 | 54 |
0 | 0 | # Makefile for ACPI daemon |
1 | 1 | |
2 | 2 | # update these numbers for new releases |
3 | VERSION = 2.0.3 | |
3 | VERSION = 2.0.4 | |
4 | 4 | |
5 | 5 | OPT = -O2 |
6 | 6 | |
55 | 55 | install -m 0755 acpi_listen $(DESTDIR)/$(BINDIR) |
56 | 56 | mkdir -p $(DESTDIR)/$(MANDIR)/man8 |
57 | 57 | install -m 0644 $(MAN8GZ) $(DESTDIR)/$(MANDIR)/man8 |
58 | # If DESTDIR is empty and mandb exists, run it | |
59 | # The following does not work when DESTDIR is not empty. | |
60 | # [ -z "$(DESTDIR)" ] && which mandb 1>/dev/null 2>&1 && mandb -q | |
61 | # This doesn't work either... | |
62 | # test -z "$(DESTDIR)" && which mandb 1>/dev/null 2>&1 && mandb -q | |
63 | # This works fine... | |
64 | if [ -z "$(DESTDIR)" ]; then \ | |
65 | which mandb 1>/dev/null 2>&1 && mandb -q; \ | |
66 | fi | |
67 | # All of the above work directly in bash, so make must be doing something | |
68 | # to break them. Any ideas? | |
69 | # Could we use make's "ifeq" to do this? | |
70 | #ifeq ($(DESTDIR),) | |
71 | # which mandb 1>/dev/null 2>&1 && mandb -q | |
72 | #endif | |
58 | # You might want to run mandb(8) after install in case your system uses it. | |
73 | 59 | |
74 | 60 | DISTTMP=/tmp |
75 | 61 | DISTNAME=acpid-$(VERSION) |
43 | 43 | static int handle_cmdline(int *argc, char ***argv); |
44 | 44 | static void close_fds(void); |
45 | 45 | static int daemonize(void); |
46 | static int open_log(void); | |
46 | static void open_log(void); | |
47 | static int std2null(void); | |
47 | 48 | static int create_pidfile(void); |
48 | 49 | static void clean_exit(int sig); |
49 | 50 | static void reload_conf(int sig); |
75 | 76 | /* close any extra file descriptors */ |
76 | 77 | close_fds(); |
77 | 78 | |
79 | /* open the log */ | |
80 | open_log(); | |
81 | ||
78 | 82 | if (!netlink) |
79 | 83 | { |
80 | 84 | /* open the acpi event file in the proc fs */ |
106 | 110 | exit(EXIT_FAILURE); |
107 | 111 | } |
108 | 112 | |
109 | /* open the log */ | |
110 | if (open_log() < 0) { | |
113 | /* redirect standard files to /dev/null */ | |
114 | if (std2null() < 0) { | |
111 | 115 | exit(EXIT_FAILURE); |
112 | 116 | } |
117 | ||
113 | 118 | acpid_log(LOG_INFO, "starting up with %s\n", |
114 | 119 | netlink ? "netlink and the input layer" : "proc fs"); |
115 | 120 | |
332 | 337 | /* fork off the parent process */ |
333 | 338 | pid = fork(); |
334 | 339 | if (pid < 0) { |
335 | fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); | |
340 | acpid_log(LOG_ERR, "fork: %s\n", strerror(errno)); | |
336 | 341 | return -1; |
337 | 342 | } |
338 | 343 | /* if we got a good PID, then we can exit the parent process */ |
350 | 355 | /* detach the process from the parent (normally a shell) */ |
351 | 356 | sid = setsid(); |
352 | 357 | if (sid < 0) { |
353 | fprintf(stderr, "%s: setsid: %s\n", progname, strerror(errno)); | |
358 | acpid_log(LOG_ERR, "setsid: %s\n", strerror(errno)); | |
354 | 359 | return -1; |
355 | 360 | } |
356 | 361 | |
357 | 362 | /* Change the current working directory. This prevents the current |
358 | 363 | directory from being locked; hence not being able to remove it. */ |
359 | 364 | if (chdir("/") < 0) { |
360 | fprintf(stderr, "%s: chdir(\"/\"): %s\n", progname, | |
361 | strerror(errno)); | |
365 | acpid_log(LOG_ERR, "chdir(\"/\"): %s\n", strerror(errno)); | |
362 | 366 | return -1; |
363 | 367 | } |
364 | 368 | |
365 | 369 | return 0; |
366 | 370 | } |
367 | 371 | |
372 | static void | |
373 | open_log(void) | |
374 | { | |
375 | int log_opts; | |
376 | ||
377 | /* open the syslog */ | |
378 | log_opts = LOG_CONS|LOG_NDELAY; | |
379 | if (acpid_debug) { | |
380 | log_opts |= LOG_PERROR; | |
381 | } | |
382 | openlog(PACKAGE, log_opts, LOG_DAEMON); | |
383 | } | |
384 | ||
368 | 385 | static int |
369 | open_log(void) | |
386 | std2null(void) | |
370 | 387 | { |
371 | 388 | int nullfd; |
372 | int log_opts; | |
373 | 389 | |
374 | 390 | /* open /dev/null */ |
375 | 391 | nullfd = open("/dev/null", O_RDWR); |
376 | 392 | if (nullfd < 0) { |
377 | fprintf(stderr, "%s: can't open %s: %s\n", progname, | |
378 | "/dev/null", strerror(errno)); | |
379 | return -1; | |
380 | } | |
381 | ||
382 | log_opts = LOG_CONS|LOG_NDELAY; | |
383 | if (acpid_debug) { | |
384 | log_opts |= LOG_PERROR; | |
385 | } | |
386 | openlog(PACKAGE, log_opts, LOG_DAEMON); | |
393 | acpid_log(LOG_ERR, "can't open /dev/null: %s\n", strerror(errno)); | |
394 | return -1; | |
395 | } | |
387 | 396 | |
388 | 397 | /* set up stdin, stdout, stderr to /dev/null */ |
389 | 398 | if (dup2(nullfd, STDIN_FILENO) != STDIN_FILENO) { |
390 | fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); | |
399 | acpid_log(LOG_ERR, "dup2() stdin: %s\n", strerror(errno)); | |
391 | 400 | return -1; |
392 | 401 | } |
393 | 402 | if (!acpid_debug && dup2(nullfd, STDOUT_FILENO) != STDOUT_FILENO) { |
394 | fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); | |
403 | acpid_log(LOG_ERR, "dup2() stdout: %s\n", strerror(errno)); | |
395 | 404 | return -1; |
396 | 405 | } |
397 | 406 | if (!acpid_debug && dup2(nullfd, STDERR_FILENO) != STDERR_FILENO) { |
398 | fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); | |
407 | acpid_log(LOG_ERR, "dup2() stderr: %s\n", strerror(errno)); | |
399 | 408 | return -1; |
400 | 409 | } |
401 | 410 | |
465 | 474 | { |
466 | 475 | va_list args; |
467 | 476 | |
468 | va_start(args, fmt); | |
469 | vsyslog(level, fmt, args); | |
470 | va_end(args); | |
477 | if (level == LOG_DEBUG) { | |
478 | /* if "-d" has been specified */ | |
479 | if (acpid_debug) { | |
480 | /* send debug output to stderr */ | |
481 | va_start(args, fmt); | |
482 | vfprintf(stderr, fmt, args); | |
483 | va_end(args); | |
484 | } | |
485 | } else { | |
486 | va_start(args, fmt); | |
487 | vsyslog(level, fmt, args); | |
488 | va_end(args); | |
489 | } | |
471 | 490 | |
472 | 491 | return 0; |
473 | 492 | } |
480 | 499 | /* check for existence of a lockfile */ |
481 | 500 | return (stat(lockfile, &trash) == 0); |
482 | 501 | } |
502 |
92 | 92 | } |
93 | 93 | } |
94 | 94 | |
95 | /* prepare for recalculation of highestfd */ | |
96 | highestfd = -2; | |
97 | ||
98 | /* recalculate highestfd */ | |
99 | for (i = 0; i < nconnections; ++i) { | |
100 | highestfd = max(highestfd, connection_list[i].fd); | |
101 | } | |
95 | /* prepare for recalculation of highestfd */ | |
96 | highestfd = -2; | |
97 | ||
98 | /* recalculate highestfd */ | |
99 | for (i = 0; i < nconnections; ++i) { | |
100 | highestfd = max(highestfd, connection_list[i].fd); | |
101 | } | |
102 | 102 | } |
103 | 103 | |
104 | 104 | /*---------------------------------------------------------------*/ |
0 | acpid (1:2.0.4-1) unstable; urgency=low | |
1 | ||
2 | * New Upstream version 2.0.4 | |
3 | ||
4 | -- Michael Meskes <meskes@debian.org> Thu, 22 Apr 2010 09:44:05 +0200 | |
5 | ||
0 | 6 | acpid (1:2.0.3-1) unstable; urgency=low |
1 | 7 | |
2 | 8 | * New Upstream version 2.0.3 |
123 | 123 | |
124 | 124 | /* skip any files that don't match the run-parts convention */ |
125 | 125 | if (regexec(&preg, dirent->d_name, 0, NULL, 0) != 0) { |
126 | acpid_log(LOG_DEBUG, "skipping conf file %s/%s\n", | |
126 | acpid_log(LOG_INFO, "skipping conf file %s/%s\n", | |
127 | 127 | confdir, dirent->d_name); |
128 | 128 | continue; |
129 | 129 | } |
148 | 148 | continue; /* keep trying the rest of the files */ |
149 | 149 | } |
150 | 150 | if (!S_ISREG(stat_buf.st_mode)) { |
151 | acpid_log(LOG_DEBUG, "skipping non-file %s\n", file); | |
151 | acpid_log(LOG_INFO, "skipping non-file %s\n", file); | |
152 | 152 | free(file); |
153 | 153 | continue; /* skip non-regular files */ |
154 | 154 | } |
218 | 218 | int line = 0; |
219 | 219 | struct rule *r; |
220 | 220 | |
221 | if (acpid_debug) { | |
222 | acpid_log(LOG_DEBUG, "parsing conf file %s\n", file); | |
223 | } | |
221 | acpid_log(LOG_DEBUG, "parsing conf file %s\n", file); | |
224 | 222 | |
225 | 223 | fp = fopen(file, "r"); |
226 | 224 | if (!fp) { |
322 | 320 | } |
323 | 321 | } |
324 | 322 | if (!r->event || !r->action.cmd) { |
325 | if (acpid_debug) { | |
326 | acpid_log(LOG_DEBUG, "skipping incomplete file %s\n", | |
327 | file); | |
328 | } | |
323 | acpid_log(LOG_INFO, "skipping incomplete file %s\n", file); | |
329 | 324 | free_rule(r); |
330 | 325 | fclose(fp); |
331 | 326 | return NULL; |
535 | 530 | struct rule *pnext = p->next; |
536 | 531 | if (!regexec(p->event, event, 0, NULL, 0)) { |
537 | 532 | /* a match! */ |
538 | if (acpid_debug && logevents) { | |
539 | acpid_log(LOG_DEBUG, | |
533 | if (logevents) { | |
534 | acpid_log(LOG_INFO, | |
540 | 535 | "rule from %s matched\n", |
541 | 536 | p->origin); |
542 | 537 | } |
552 | 547 | } |
553 | 548 | } else { |
554 | 549 | if (acpid_debug >= 3 && logevents) { |
555 | acpid_log(LOG_DEBUG, | |
550 | acpid_log(LOG_INFO, | |
556 | 551 | "rule from %s did not match\n", |
557 | 552 | p->origin); |
558 | 553 | } |
563 | 558 | |
564 | 559 | unlock_rules(); |
565 | 560 | |
566 | if (acpid_debug && logevents) { | |
567 | acpid_log(LOG_DEBUG, "%d total rule%s matched\n", | |
561 | if (logevents) { | |
562 | acpid_log(LOG_INFO, "%d total rule%s matched\n", | |
568 | 563 | nrules, (nrules == 1)?"":"s"); |
569 | 564 | } |
570 | 565 |
48 | 48 | |
49 | 49 | bytes = read(fd, &eventbuf.buffer, sizeof(eventbuf.buffer)); |
50 | 50 | |
51 | if (acpid_debug) | |
52 | fprintf(stderr, "%s: inotify read bytes: %d\n", progname, bytes); | |
51 | acpid_log(LOG_DEBUG, "inotify read bytes: %d\n", bytes); | |
53 | 52 | |
54 | 53 | /* eof is not expected */ |
55 | 54 | if (bytes == 0) |
67 | 66 | return; |
68 | 67 | } |
69 | 68 | |
70 | if (acpid_debug) | |
71 | fprintf(stderr, "%s: inotify name len: %d\n", | |
72 | progname, eventbuf.event.len); | |
69 | acpid_log(LOG_DEBUG, "inotify name len: %d\n", eventbuf.event.len); | |
73 | 70 | |
74 | 71 | /* if a name is included */ |
75 | 72 | if (eventbuf.event.len > 0) |
82 | 79 | strcat(devname, "/"); |
83 | 80 | strncat(devname, eventbuf.event.name, dnsize - strlen(devname) - 1); |
84 | 81 | |
85 | if (acpid_debug) | |
86 | fprintf(stderr, "%s: inotify about to open: %s\n", | |
87 | progname, devname); | |
82 | acpid_log(LOG_DEBUG, "inotify about to open: %s\n", devname); | |
88 | 83 | |
89 | 84 | open_inputfile(devname); |
90 | 85 | } |
107 | 102 | return; |
108 | 103 | } |
109 | 104 | |
110 | if (acpid_debug) | |
111 | fprintf(stderr, "%s: inotify fd: %d\n", progname, fd); | |
105 | acpid_log(LOG_DEBUG, "inotify fd: %d\n", fd); | |
112 | 106 | |
113 | 107 | /* watch for new files being created in /dev/input */ |
114 | 108 | wd = inotify_add_watch(fd, ACPID_INPUTLAYERDIR, IN_CREATE); |
120 | 114 | return; |
121 | 115 | } |
122 | 116 | |
123 | if (acpid_debug) | |
124 | fprintf(stderr, "%s: inotify wd: %d\n", progname, wd); | |
117 | acpid_log(LOG_DEBUG, "inotify wd: %d\n", wd); | |
125 | 118 | |
126 | 119 | /* add a connection to the list */ |
127 | 120 | c.fd = fd; |
298 | 298 | return -1; |
299 | 299 | } |
300 | 300 | |
301 | if (acpid_debug) | |
302 | fprintf(stderr, "%s: input layer %s " | |
303 | "opened successfully\n", progname, filename); | |
301 | acpid_log(LOG_DEBUG, "input layer %s " | |
302 | "opened successfully\n", filename); | |
304 | 303 | |
305 | 304 | /* add a connection to the list */ |
306 | 305 | c.fd = fd; |
336 | 335 | } |
337 | 336 | |
338 | 337 | if (!success) |
339 | fprintf(stderr, "%s: cannot open input layer\n", progname); | |
338 | acpid_log(LOG_ERR, "cannot open input layer\n"); | |
340 | 339 | |
341 | 340 | globfree(&globbuf); |
342 | 341 | } |
208 | 208 | nl_mgrp(__u32 group) |
209 | 209 | { |
210 | 210 | if (group > 31) { |
211 | fprintf(stderr, "%s: unexpected group number %d\n", | |
212 | progname, group); | |
211 | acpid_log(LOG_ERR, "Unexpected group number %d\n", group); | |
213 | 212 | return 0; |
214 | 213 | } |
215 | 214 | return group ? (1 << (group - 1)) : 0; |
223 | 222 | /* open the appropriate netlink socket for input */ |
224 | 223 | if (rtnl_open_byproto( |
225 | 224 | &rth, nl_mgrp(acpi_ids_getgroup()), NETLINK_GENERIC) < 0) { |
226 | fprintf(stderr, "%s: cannot open generic netlink socket\n", | |
227 | progname); | |
228 | return; | |
229 | } | |
230 | ||
231 | if (acpid_debug) | |
232 | fprintf(stderr, "%s: netlink opened successfully\n", progname); | |
225 | acpid_log(LOG_ERR, "cannot open generic netlink socket\n"); | |
226 | return; | |
227 | } | |
228 | ||
229 | acpid_log(LOG_DEBUG, "netlink opened successfully\n"); | |
233 | 230 | |
234 | 231 | /* add a connection to the list */ |
235 | 232 | c.fd = rth.fd; |
236 | 233 | c.process = process_netlink; |
237 | 234 | add_connection(&c); |
238 | 235 | } |
236 |
86 | 86 | |
87 | 87 | fd = open(eventfile, O_RDONLY); |
88 | 88 | if (fd < 0) { |
89 | if (acpid_debug) | |
90 | fprintf(stderr, "%s: can't open %s: %s\n", progname, | |
91 | eventfile, strerror(errno)); | |
89 | if (errno == ENOENT) { | |
90 | acpid_log(LOG_INFO, "Deprecated %s was not found. " | |
91 | "Trying netlink and the input layer...\n", eventfile); | |
92 | } else { | |
93 | acpid_log(LOG_ERR, "can't open %s: %s (%d)\n", eventfile, | |
94 | strerror(errno), errno); | |
95 | } | |
92 | 96 | return -1; |
97 | ||
93 | 98 | } |
94 | 99 | fcntl(fd, F_SETFD, FD_CLOEXEC); |
95 | 100 | |
96 | if (acpid_debug) | |
97 | fprintf(stderr, "%s: proc fs opened successfully\n", progname); | |
101 | acpid_log(LOG_DEBUG, "proc fs opened successfully\n"); | |
98 | 102 | |
99 | 103 | /* add a connection to the list */ |
100 | 104 | c.fd = fd; |
0 | # This sample acpid configuration file goes with the acpi_handler.sh | |
1 | # handler script to show how one can handle all events within a single | |
2 | # script. | |
3 | ||
4 | event=* | |
5 | action=acpi_handler.sh "%e" |
0 | 0 | #!/bin/sh |
1 | # a sample skeleton for handling ACPI events | |
1 | # A sample skeleton for handling ACPI events. | |
2 | # See acpi_handler-conf for a configuration file that can be used to | |
3 | # run this script. | |
2 | 4 | |
3 | 5 | if [ $# != 1 ]; then |
4 | 6 | exit 1 |
0 | # /etc/acpid/events/battery | |
1 | # This detects changes to AC connector status, and passes them to | |
2 | # /etc/acpi/battery.sh for further processing. | |
3 | ||
4 | # Optionally you can specify the placeholder %e. It will pass | |
5 | # through the whole kernel event message to the program you've | |
6 | # specified. | |
7 | ||
8 | event=battery | |
9 | action=/etc/acpi/battery.sh |
0 | # /etc/acpid/events/battery | |
1 | # This detects changes to AC connector status, and passes them to | |
2 | # /etc/acpi/battery.sh for further processing. | |
3 | ||
4 | # Optionally you can specify the placeholder %e. It will pass | |
5 | # through the whole kernel event message to the program you've | |
6 | # specified. | |
7 | ||
8 | event=battery | |
9 | action=/etc/acpi/battery.sh |
0 | # This is a sample acpid configuration file. See the man page for | |
1 | # acpid which describes this configuration file. | |
2 | # When a button/power event is received, the power.sh script is run. | |
3 | ||
4 | event=button/power | |
5 | action=/etc/acpid/power.sh | |
6 |
0 | #!/bin/bash | |
1 | # This script is triggered by the "power" configuration file. This is | |
2 | # described in the acpid man page. | |
3 | ||
4 | # A much more comprehensive power button handler is provided in the | |
5 | # powerbtn directory in this samples directory. If you run gnome or KDE, | |
6 | # it's better to use that one instead of this one. | |
7 | ||
8 | /sbin/shutdown -h now "Power button pressed" | |
9 |
0 | # /etc/acpi/events/powerbtn | |
1 | # This is called when the user presses the power button and calls | |
2 | # /etc/acpi/powerbtn.sh for further processing. | |
3 | ||
4 | # Optionally you can specify the placeholder %e. It will pass | |
5 | # through the whole kernel event message to the program you've | |
6 | # specified. | |
7 | ||
8 | # We need to react on "button power.*" and "button/power.*" because | |
9 | # of kernel changes. | |
10 | ||
11 | event=button[ /]power | |
12 | action=/etc/acpi/powerbtn.sh |
0 | #!/bin/sh | |
1 | # /etc/acpi/powerbtn.sh | |
2 | # Taken from the 11/14/2008 version from Debian. | |
3 | # Power Button event handler. | |
4 | # Checks to see if gnome or KDE are already handling the power button. | |
5 | # If not, initiates a plain shutdown. | |
6 | ||
7 | # Skip if we are in the middle of resuming. Otherwise we may power down the | |
8 | # system as it is coming back up. | |
9 | # See 98-acpi-unlock.sh and 05-acpi-lock.sh in Debian. | |
10 | test -f /var/lock/acpisleep && exit 0 | |
11 | ||
12 | # If gnome-power-manager, kpowersave or klaptopdaemon are running... | |
13 | if pidof gnome-power-manager kpowersave > /dev/null || | |
14 | (pidof dcopserver > /dev/null && test -x /usr/bin/dcop && /usr/bin/dcop kded kded loadedModules | grep -q klaptopdaemon) ; then | |
15 | # Let them handle the power button. | |
16 | exit | |
17 | fi | |
18 | ||
19 | # If KDE is running... | |
20 | if ps -Af | grep -q '[k]desktop' && pidof dcopserver > /dev/null && test -x /usr/bin/dcop ; then | |
21 | # Ask it to logout. | |
22 | KDESES=`pidof dcopserver | wc -w` | |
23 | if [ $KDESES -eq 1 ] ; then | |
24 | # single KDE session -> ask user | |
25 | /usr/bin/dcop --all-sessions --all-users ksmserver ksmserver logout 1 2 0 | |
26 | exit 0 | |
27 | else | |
28 | # more than one KDE session - just send shutdown signal to all of them | |
29 | /usr/bin/dcop --all-sessions --all-users ksmserver ksmserver logout 0 2 0 && exit 0 | |
30 | fi | |
31 | fi | |
32 | ||
33 | # Initiate a plain shutdown. | |
34 | /sbin/shutdown -h now "Power button pressed" | |
35 |
0 | # This is a sample ACPID configuration | |
1 | ||
2 | # event=button/power | |
3 | # action=/usr/local/bin/power.sh "%e" |
20 | 20 | */ |
21 | 21 | |
22 | 22 | #include <unistd.h> |
23 | #include <sys/types.h> | |
24 | #include <sys/stat.h> | |
23 | #include <sys/types.h> | |
24 | #include <sys/stat.h> | |
25 | 25 | #include <fcntl.h> |
26 | 26 | #include <stdio.h> |
27 | 27 | #include <stdlib.h> |
86 | 86 | |
87 | 87 | fd = ud_create_socket(socketfile); |
88 | 88 | if (fd < 0) { |
89 | fprintf(stderr, "%s: can't open socket %s: %s\n", | |
90 | progname, socketfile, strerror(errno)); | |
89 | acpid_log(LOG_ERR, "can't open socket %s: %s\n", | |
90 | socketfile, strerror(errno)); | |
91 | 91 | exit(EXIT_FAILURE); |
92 | 92 | } |
93 | 93 | fcntl(fd, F_SETFD, FD_CLOEXEC); |
97 | 97 | struct stat buf; |
98 | 98 | gr = getgrnam(socketgroup); |
99 | 99 | if (!gr) { |
100 | fprintf(stderr, "%s: group %s does not exist\n", | |
101 | progname, socketgroup); | |
100 | acpid_log(LOG_ERR, "group %s does not exist\n", socketgroup); | |
102 | 101 | exit(EXIT_FAILURE); |
103 | 102 | } |
104 | 103 | if (stat(socketfile, &buf) < 0) { |
105 | fprintf(stderr, "%s: can't stat %s\n", | |
106 | progname, socketfile); | |
104 | acpid_log(LOG_ERR, "can't stat %s\n", socketfile); | |
107 | 105 | exit(EXIT_FAILURE); |
108 | 106 | } |
109 | 107 | if (chown(socketfile, buf.st_uid, gr->gr_gid) < 0) { |
110 | fprintf(stderr, "%s: chown(): %s\n", | |
111 | progname, strerror(errno)); | |
108 | acpid_log(LOG_ERR, "can't chown: %s\n", strerror(errno)); | |
112 | 109 | exit(EXIT_FAILURE); |
113 | 110 | } |
114 | 111 | } |
118 | 115 | c.process = process_sock; |
119 | 116 | add_connection(&c); |
120 | 117 | } |
118 |