00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <sys/types.h>
00023 #include <sys/stat.h>
00024 #include <fcntl.h>
00025 #include <signal.h>
00026 #include <unistd.h>
00027 #include <stdio.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 #include <ctype.h>
00032 #include <getopt.h>
00033 #include <time.h>
00034 #include <sys/poll.h>
00035 #include <grp.h>
00036 #include <signal.h>
00037
00038 #include "acpid.h"
00039 #include "ud_socket.h"
00040
00041 static int handle_cmdline(int *argc, char ***argv);
00042 static char *read_line(int fd);
00043
00044 static const char *progname;
00045 static const char *socketfile = ACPI_SOCKETFILE;
00046 static int max_events;
00047
00048 static void
00049 time_expired(int signum)
00050 {
00051 exit(EXIT_SUCCESS);
00052 }
00053
00054 int
00055 main(int argc, char **argv)
00056 {
00057 int sock_fd;
00058 int ret;
00059
00060
00061 signal(SIGALRM, time_expired);
00062
00063
00064 progname = (const char *)strrchr(argv[0], '/');
00065 progname = progname ? (progname + 1) : argv[0];
00066
00067
00068 handle_cmdline(&argc, &argv);
00069
00070
00071 sock_fd = ud_connect(socketfile);
00072 if (sock_fd < 0) {
00073 fprintf(stderr, "%s: can't open socket %s: %s\n",
00074 progname, socketfile, strerror(errno));
00075 exit(EXIT_FAILURE);
00076 }
00077 fcntl(sock_fd, F_SETFD, FD_CLOEXEC);
00078
00079
00080 setvbuf(stdout, NULL, _IOLBF, 0);
00081
00082
00083 ret = 0;
00084 while (1) {
00085 char *event;
00086
00087
00088 event = read_line(sock_fd);
00089 if (event) {
00090 fprintf(stdout, "%s\n", event);
00091 } else if (errno == EPIPE) {
00092 fprintf(stderr, "connection closed\n");
00093 break;
00094 } else {
00095 static int nerrs;
00096 if (++nerrs >= ACPI_MAX_ERRS) {
00097 fprintf(stderr, "too many errors - aborting\n");
00098 ret = 1;
00099 break;
00100 }
00101 }
00102
00103 if (max_events > 0 && --max_events == 0) {
00104 break;
00105 }
00106 }
00107
00108 return ret;
00109 }
00110
00111 static struct option opts[] = {
00112 {"count", 0, 0, 'c'},
00113 {"socketfile", 1, 0, 's'},
00114 {"time", 0, 0, 't'},
00115 {"version", 0, 0, 'v'},
00116 {"help", 0, 0, 'h'},
00117 {NULL, 0, 0, 0},
00118 };
00119 static const char *opts_help[] = {
00120 "Set the maximum number of events.",
00121 "Use the specified socket file.",
00122 "Listen for the specified time (in seconds).",
00123 "Print version information.",
00124 "Print this message.",
00125 };
00126
00127 static void
00128 usage(FILE *fp)
00129 {
00130 struct option *opt;
00131 const char **hlp;
00132 int max, size;
00133
00134 fprintf(fp, "Usage: %s [OPTIONS]\n", progname);
00135 max = 0;
00136 for (opt = opts; opt->name; opt++) {
00137 size = strlen(opt->name);
00138 if (size > max)
00139 max = size;
00140 }
00141 for (opt = opts, hlp = opts_help; opt->name; opt++, hlp++) {
00142 fprintf(fp, " -%c, --%s", opt->val, opt->name);
00143 size = strlen(opt->name);
00144 for (; size < max; size++)
00145 fprintf(fp, " ");
00146 fprintf(fp, " %s\n", *hlp);
00147 }
00148 }
00149
00150
00151
00152
00153 static int
00154 handle_cmdline(int *argc, char ***argv)
00155 {
00156 for (;;) {
00157 int i;
00158 i = getopt_long(*argc, *argv, "c:s:t:vh", opts, NULL);
00159 if (i == -1) {
00160 break;
00161 }
00162 switch (i) {
00163 case 'c':
00164 if (!isdigit(optarg[0])) {
00165 usage(stderr);
00166 exit(EXIT_FAILURE);
00167 }
00168 max_events = atoi(optarg);
00169 break;
00170 case 's':
00171 socketfile = optarg;
00172 break;
00173 case 't':
00174 if (!isdigit(optarg[0])) {
00175 usage(stderr);
00176 exit(EXIT_FAILURE);
00177 }
00178 alarm(atoi(optarg));
00179 break;
00180 case 'v':
00181 printf(PACKAGE "-" VERSION "\n");
00182 exit(EXIT_SUCCESS);
00183 case 'h':
00184 usage(stdout);
00185 exit(EXIT_SUCCESS);
00186 default:
00187 usage(stderr);
00188 exit(EXIT_FAILURE);
00189 break;
00190 }
00191 }
00192
00193 *argc -= optind;
00194 *argv += optind;
00195
00196 return 0;
00197 }
00198
00199 #define MAX_BUFLEN 1024
00200 static char *
00201 read_line(int fd)
00202 {
00203 static char *buf;
00204 int buflen = 64;
00205 int i = 0;
00206 int r;
00207 int searching = 1;
00208
00209 while (searching) {
00210 buf = realloc(buf, buflen);
00211 if (!buf) {
00212 fprintf(stderr, "ERR: malloc(%d): %s\n",
00213 buflen, strerror(errno));
00214 return NULL;
00215 }
00216 memset(buf+i, 0, buflen-i);
00217
00218 while (i < buflen) {
00219 r = read(fd, buf+i, 1);
00220 if (r < 0 && errno != EINTR) {
00221
00222 fprintf(stderr, "ERR: read(): %s\n",
00223 strerror(errno));
00224 return NULL;
00225 } else if (r == 0) {
00226
00227 errno = EPIPE;
00228 return NULL;
00229 } else if (r == 1) {
00230
00231 if (buf[i] == '\n') {
00232 searching = 0;
00233 buf[i] = '\0';
00234 break;
00235 }
00236 i++;
00237 }
00238 }
00239 if (buflen >= MAX_BUFLEN) {
00240 break;
00241 }
00242 buflen *= 2;
00243 }
00244
00245 return buf;
00246 }