2 * acpi_listen.c - ACPI client for acpid's UNIX socket
4 * Portions Copyright (C) 2003 Sun Microsystems (thockin@sun.com)
5 * Some parts (C) 2003 - Gismo / Luca Capello <luca.pca.it> http://luca.pca.it
6 * Copyright (C) 2004 Tim Hockin (thockin@hockin.org)
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 #include <sys/types.h>
40 #include "ud_socket.h"
42 static int handle_cmdline(int *argc, char ***argv);
43 static char *read_line(int fd);
46 const char *socketfile = ACPID_SOCKETFILE;
47 static int max_events;
50 time_expired(int signum __attribute__((unused)))
56 main(int argc, char **argv)
62 signal(SIGALRM, time_expired);
64 /* learn who we really are */
65 progname = (const char *)strrchr(argv[0], '/');
66 progname = progname ? (progname + 1) : argv[0];
68 /* handle the commandline */
69 handle_cmdline(&argc, &argv);
72 sock_fd = ud_connect(socketfile);
74 fprintf(stderr, "%s: can't open socket %s: %s\n",
75 progname, socketfile, strerror(errno));
78 fcntl(sock_fd, F_SETFD, FD_CLOEXEC);
80 /* set stdout to be line buffered */
81 setvbuf(stdout, NULL, _IOLBF, 0);
88 /* read and handle an event */
89 event = read_line(sock_fd);
91 fprintf(stdout, "%s\n", event);
92 } else if (errno == EPIPE) {
93 fprintf(stderr, "connection closed\n");
97 if (++nerrs >= ACPID_MAX_ERRS) {
98 fprintf(stderr, "too many errors - aborting\n");
104 if (max_events > 0 && --max_events == 0) {
112 static struct option opts[] = {
113 {"count", 0, 0, 'c'},
114 {"socketfile", 1, 0, 's'},
116 {"version", 0, 0, 'v'},
120 static const char *opts_help[] = {
121 "Set the maximum number of events.", /* count */
122 "Use the specified socket file.", /* socketfile */
123 "Listen for the specified time (in seconds).",/* time */
124 "Print version information.", /* version */
125 "Print this message.", /* help */
135 fprintf(fp, "Usage: %s [OPTIONS]\n", progname);
137 for (opt = opts; opt->name; opt++) {
138 size = strlen(opt->name);
142 for (opt = opts, hlp = opts_help; opt->name; opt++, hlp++) {
143 fprintf(fp, " -%c, --%s", opt->val, opt->name);
144 size = strlen(opt->name);
145 for (; size < max; size++)
147 fprintf(fp, " %s\n", *hlp);
152 * Parse command line arguments
155 handle_cmdline(int *argc, char ***argv)
159 i = getopt_long(*argc, *argv, "c:s:t:vh", opts, NULL);
165 if (!isdigit(optarg[0])) {
169 max_events = atoi(optarg);
175 if (!isdigit(optarg[0])) {
182 printf(PACKAGE "-" VERSION "\n");
200 #define MAX_BUFLEN 1024
211 buf = realloc(buf, buflen);
213 fprintf(stderr, "ERR: malloc(%d): %s\n",
214 buflen, strerror(errno));
217 memset(buf+i, 0, buflen-i);
220 r = read(fd, buf+i, 1);
221 if (r < 0 && errno != EINTR) {
222 /* we should do something with the data */
223 fprintf(stderr, "ERR: read(): %s\n",
227 /* signal this in an almost standard way */
231 /* scan for a newline */
232 if (buf[i] == '\n') {
240 if (buflen >= MAX_BUFLEN) {