#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <signal.h>#include <unistd.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include <getopt.h>#include <time.h>#include <sys/poll.h>#include <grp.h>#include "acpid.h"#include "ud_socket.h"Go to the source code of this file.
Defines | |
| #define | MAX_BUFLEN 1024 |
Functions | |
| static int | handle_cmdline (int *argc, char ***argv) |
| static void | close_fds (void) |
| static int | daemonize (void) |
| static int | open_logs (void) |
| static void | clean_exit (int sig) |
| static void | reload_conf (int sig) |
| static char * | read_line (int fd) |
| int | main (int argc, char **argv) |
| int | acpid_log (const char *fmt,...) |
Variables | |
| int | acpid_debug |
| static const char * | progname |
| static const char * | confdir = ACPI_CONFDIR |
| static const char * | logfile = ACPI_LOGFILE |
| static const char * | eventfile = ACPI_EVENTFILE |
| static const char * | socketfile = ACPI_SOCKETFILE |
| static int | nosocket |
| static const char * | socketgroup |
| static mode_t | socketmode = ACPI_SOCKETMODE |
| static int | foreground |
|
|
|
|
||||||||||||
|
Definition at line 450 of file acpid.c. Referenced by acpid_add_client(), acpid_cleanup_rules(), acpid_handle_event(), acpid_read_conf(), check_escapes(), clean_exit(), do_client_rule(), do_cmd_rule(), lock_rules(), main(), new_rule(), parse_client(), parse_cmd(), parse_file(), path_is_dir(), read_line(), reload_conf(), safe_write(), and unlock_rules(). 00451 { 00452 va_list args; 00453 int len = 0; 00454 time_t curtime; 00455 char *timestr; 00456 00457 va_start(args, fmt); 00458 curtime = time(NULL); 00459 timestr = ctime(&curtime); 00460 timestr[strlen(timestr)-1] = '\0'; 00461 len += fprintf(stderr, "[%s] ", timestr); 00462 len += vfprintf(stderr, fmt, args); 00463 va_end(args); 00464 00465 return 0; 00466 }
|
|
|
Definition at line 434 of file acpid.c. References acpid_cleanup_rules(), and acpid_log(). Referenced by main(). 00435 { 00436 acpid_cleanup_rules(); 00437 acpid_log("exiting\n"); 00438 exit(EXIT_SUCCESS); 00439 }
|
|
|
Definition at line 361 of file acpid.c. Referenced by main(). 00362 { 00363 int fd, max; 00364 max = sysconf(_SC_OPEN_MAX); 00365 for (fd = 3; fd < max; fd++) 00366 close(fd); 00367 }
|
|
|
Definition at line 370 of file acpid.c. References progname. Referenced by main(). 00371 { 00372 switch(fork()) { 00373 case -1: 00374 fprintf(stderr, "%s: fork: %s\n", progname, strerror(errno)); 00375 return -1; 00376 case 0: 00377 /* child */ 00378 break; 00379 default: 00380 /* parent */ 00381 exit(EXIT_SUCCESS); 00382 } 00383 00384 /* disconnect */ 00385 setsid(); 00386 umask(0); 00387 00388 /* get outta the way */ 00389 chdir("/"); 00390 00391 return 0; 00392 }
|
|
||||||||||||
|
Definition at line 258 of file acpid.c. References acpid_debug, confdir, eventfile, foreground, logfile, nosocket, opts_help, PACKAGE, progname, socketfile, socketgroup, and socketmode. 00259 { 00260 struct option opts[] = { 00261 {"confdir", 1, 0, 'c'}, 00262 {"debug", 0, 0, 'd'}, 00263 {"eventfile", 1, 0, 'e'}, 00264 {"foreground", 0, 0, 'f'}, 00265 {"socketgroup", 1, 0, 'g'}, 00266 {"logfile", 1, 0, 'l'}, 00267 {"socketmode", 1, 0, 'm'}, 00268 {"socketfile", 1, 0, 's'}, 00269 {"nosocket", 1, 0, 'S'}, 00270 {"version", 0, 0, 'v'}, 00271 {"help", 0, 0, 'h'}, 00272 {NULL, 0, 0, 0}, 00273 }; 00274 const char *opts_help[] = { 00275 "Set the configuration directory.", /* confdir */ 00276 "Increase debugging level (implies -f).",/* debug */ 00277 "Use the specified file for events.", /* eventfile */ 00278 "Run in the foreground.", /* foreground */ 00279 "Set the group on the socket file.", /* socketgroup */ 00280 "Use the specified log file.", /* logfile */ 00281 "Set the permissions on the socket file.",/* socketmode */ 00282 "Use the specified socket file.", /* socketfile */ 00283 "Do not listen on a UNIX socket (overrides -s).",/* nosocket */ 00284 "Print version information.", /* version */ 00285 "Print this message.", /* help */ 00286 }; 00287 struct option *opt; 00288 const char **hlp; 00289 int max, size; 00290 00291 for (;;) { 00292 int i; 00293 i = getopt_long(*argc, *argv, "c:de:fg:l:m:s:Svh", opts, NULL); 00294 if (i == -1) { 00295 break; 00296 } 00297 switch (i) { 00298 case 'c': 00299 confdir = optarg; 00300 break; 00301 case 'd': 00302 foreground = 1; 00303 acpid_debug++; 00304 break; 00305 case 'e': 00306 eventfile = optarg; 00307 break; 00308 case 'f': 00309 foreground = 1; 00310 break; 00311 case 'g': 00312 socketgroup = optarg; 00313 break; 00314 case 'l': 00315 logfile = optarg; 00316 break; 00317 case 'm': 00318 socketmode = strtol(optarg, NULL, 8); 00319 break; 00320 case 's': 00321 socketfile = optarg; 00322 break; 00323 case 'S': 00324 nosocket = 1; 00325 break; 00326 case 'v': 00327 printf(PACKAGE "-" VERSION "\n"); 00328 exit(EXIT_SUCCESS); 00329 case 'h': 00330 default: 00331 fprintf(stderr, "Usage: %s [OPTIONS]\n", progname); 00332 max = 0; 00333 for (opt = opts; opt->name; opt++) { 00334 size = strlen(opt->name); 00335 if (size > max) 00336 max = size; 00337 } 00338 for (opt = opts, hlp = opts_help; 00339 opt->name; 00340 opt++, hlp++) 00341 { 00342 fprintf(stderr, " -%c, --%s", 00343 opt->val, opt->name); 00344 size = strlen(opt->name); 00345 for (; size < max; size++) 00346 fprintf(stderr, " "); 00347 fprintf(stderr, " %s\n", *hlp); 00348 } 00349 exit(EXIT_FAILURE); 00350 break; 00351 } 00352 } 00353 00354 *argc -= optind; 00355 *argv += optind; 00356 00357 return 0; 00358 }
|
|
||||||||||||
|
Definition at line 61 of file acpid.c. References ACPI_MAX_ERRS, acpid_add_client(), acpid_debug, acpid_handle_event(), acpid_log(), acpid_read_conf(), clean_exit(), close_fds(), confdir, daemonize(), eventfile, foreground, handle_cmdline(), nosocket, open_logs(), progname, read_line(), reload_conf(), socketfile, socketgroup, socketmode, ud_accept(), and ud_create_socket(). 00062 { 00063 int event_fd; 00064 int sock_fd; 00065 00066 /* learn who we really are */ 00067 progname = (const char *)strrchr(argv[0], '/'); 00068 progname = progname ? (progname + 1) : argv[0]; 00069 00070 /* handle the commandline */ 00071 handle_cmdline(&argc, &argv); 00072 00073 /* close any extra file descriptors */ 00074 close_fds(); 00075 00076 /* actually open the event file */ 00077 event_fd = open(eventfile, O_RDONLY); 00078 if (event_fd < 0) { 00079 fprintf(stderr, "%s: can't open %s: %s\n", progname, 00080 eventfile, strerror(errno)); 00081 exit(EXIT_FAILURE); 00082 } 00083 fcntl(event_fd, F_SETFD, FD_CLOEXEC); 00084 00085 /* 00086 * if there is data, and the kernel is NOT broken, this eats 1 byte. We 00087 * can't have that. This is ifdef'ed out on the assumption that old kernels 00088 * are out of popular use, by now. 00089 */ 00090 #ifdef TEST_FOR_BAD_KERNELS 00091 /* 00092 * Older kernels did not support read() properly or poll() at all 00093 * Check that the kernel supports the proper semantics, or die. 00094 * 00095 * Good kernels will respect O_NONBLOCK and return -1. Bad kernels 00096 * will ignore O_NONBLOCK and return 0. Really bad kernels will block 00097 * and overflow the buffer. Can't deal with the really bad ones. 00098 */ 00099 { 00100 int fl; 00101 char buf; 00102 00103 fl = fcntl(event_fd, F_GETFL); 00104 fcntl(event_fd, F_SETFL, fl | O_NONBLOCK); 00105 if (read(event_fd, &buf, 1) == 0) { 00106 fprintf(stderr, 00107 "%s: this kernel does not support proper " 00108 "event file handling.\n" 00109 "Please get the patch from " 00110 "http://acpid.sourceforge.net\n", 00111 progname); 00112 exit(EXIT_FAILURE); 00113 } 00114 fcntl(event_fd, F_SETFL, fl); 00115 } 00116 #endif 00117 00118 /* open our socket */ 00119 if (!nosocket) { 00120 sock_fd = ud_create_socket(socketfile); 00121 if (sock_fd < 0) { 00122 fprintf(stderr, "%s: can't open socket %s: %s\n", 00123 progname, socketfile, strerror(errno)); 00124 exit(EXIT_FAILURE); 00125 } 00126 fcntl(sock_fd, F_SETFD, FD_CLOEXEC); 00127 chmod(socketfile, socketmode); 00128 if (socketgroup) { 00129 struct group *gr; 00130 struct stat buf; 00131 gr = getgrnam(socketgroup); 00132 if (!gr) { 00133 fprintf(stderr, "%s: group %s does not exist\n", 00134 progname, socketgroup); 00135 exit(EXIT_FAILURE); 00136 } 00137 if (stat(socketfile, &buf) < 0) { 00138 fprintf(stderr, "%s: can't stat %s\n", 00139 progname, socketfile); 00140 exit(EXIT_FAILURE); 00141 } 00142 if (chown(socketfile, buf.st_uid, gr->gr_gid) < 0) { 00143 fprintf(stderr, "%s: chown(): %s\n", 00144 progname, strerror(errno)); 00145 exit(EXIT_FAILURE); 00146 } 00147 } 00148 } 00149 00150 /* if we're running in foreground, we don't daemonize */ 00151 if (!foreground) { 00152 if (daemonize() < 0) 00153 exit(EXIT_FAILURE); 00154 } 00155 00156 /* normal logging unless debugging */ 00157 if (!acpid_debug) { 00158 if (open_logs() < 0) 00159 exit(EXIT_FAILURE); 00160 } 00161 acpid_log("starting up\n"); 00162 00163 /* trap key signals */ 00164 signal(SIGHUP, reload_conf); 00165 signal(SIGINT, clean_exit); 00166 signal(SIGQUIT, clean_exit); 00167 signal(SIGTERM, clean_exit); 00168 signal(SIGPIPE, SIG_IGN); 00169 00170 /* read in our configuration */ 00171 acpid_read_conf(confdir); 00172 00173 /* main loop */ 00174 while (1) { 00175 struct pollfd ar[2]; 00176 int r; 00177 int fds = 0; 00178 00179 /* poll for the socket and the event file */ 00180 ar[0].fd = event_fd; ar[0].events = POLLIN; fds++; 00181 if (!nosocket) { 00182 ar[1].fd = sock_fd; ar[1].events = POLLIN; fds++; 00183 } 00184 r = poll(ar, fds, -1); 00185 00186 if (r < 0 && errno == EINTR) { 00187 continue; 00188 } else if (r < 0) { 00189 acpid_log("ERR: poll(): %s\n", strerror(errno)); 00190 continue; 00191 } 00192 00193 /* was it an event? */ 00194 if (ar[0].revents) { 00195 char *event; 00196 00197 /* this shouldn't happen */ 00198 if (!ar[0].revents & POLLIN) { 00199 acpid_log("odd, poll set flags 0x%x\n", 00200 ar[0].revents); 00201 continue; 00202 } 00203 00204 /* read and handle an event */ 00205 event = read_line(event_fd); 00206 if (event) { 00207 acpid_log("received event \"%s\"\n", event); 00208 acpid_handle_event(event); 00209 acpid_log("completed event \"%s\"\n", event); 00210 } else if (errno == EPIPE) { 00211 acpid_log("events file connection closed\n"); 00212 break; 00213 } else { 00214 static int nerrs; 00215 if (++nerrs >= ACPI_MAX_ERRS) { 00216 acpid_log("too many errors reading " 00217 "events file - aborting\n"); 00218 break; 00219 } 00220 } 00221 } 00222 00223 /* was it a new connection? */ 00224 if (!nosocket && ar[1].revents) { 00225 int cli_fd; 00226 struct ucred creds; 00227 char buf[32]; 00228 00229 /* this shouldn't happen */ 00230 if (!ar[1].revents & POLLIN) { 00231 acpid_log("odd, poll set flags 0x%x\n", 00232 ar[1].revents); 00233 continue; 00234 } 00235 00236 /* accept and add to our lists */ 00237 cli_fd = ud_accept(sock_fd, &creds); 00238 if (cli_fd < 0) { 00239 acpid_log("ERR: can't accept client: %s\n", 00240 strerror(errno)); 00241 continue; 00242 } 00243 snprintf(buf, sizeof(buf)-1, "%d[%d:%d]", 00244 creds.pid, creds.uid, creds.gid); 00245 acpid_add_client(cli_fd, buf); 00246 } 00247 } 00248 00249 clean_exit(EXIT_SUCCESS); 00250 00251 return 0; 00252 }
|
|
|
Definition at line 395 of file acpid.c. References logfile, and progname. Referenced by main(). 00396 { 00397 int logfd; 00398 int nullfd; 00399 00400 /* set up stdout, stderr to log and stdin to /dev/null */ 00401 nullfd = open("/dev/null", O_RDONLY, 0640); 00402 if (nullfd < 0) { 00403 fprintf(stderr, "%s: can't open %s: %s\n", progname, 00404 "/dev/null", strerror(errno)); 00405 return -1; 00406 } 00407 logfd = open(logfile, O_WRONLY|O_CREAT|O_APPEND); 00408 if (logfd < 0) { 00409 fprintf(stderr, "%s: can't open %s: %s\n", progname, 00410 logfile, strerror(errno)); 00411 return -1; 00412 } 00413 00414 if (dup2(nullfd, STDIN_FILENO) != STDIN_FILENO) { 00415 fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); 00416 return -1; 00417 } 00418 if (dup2(logfd, STDOUT_FILENO) != STDOUT_FILENO) { 00419 fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); 00420 return -1; 00421 } 00422 if (dup2(logfd, STDERR_FILENO) != STDERR_FILENO) { 00423 fprintf(stderr, "%s: dup2: %s\n", progname, strerror(errno)); 00424 return -1; 00425 } 00426 00427 close(nullfd); 00428 close(logfd); 00429 00430 return 0; 00431 }
|
|
|
Definition at line 473 of file acpid.c. References acpid_log(), and MAX_BUFLEN. 00474 { 00475 static char *buf; 00476 int buflen = 64; 00477 int i = 0; 00478 int r; 00479 int searching = 1; 00480 00481 while (searching) { 00482 buf = realloc(buf, buflen); 00483 if (!buf) { 00484 acpid_log("ERR: malloc(%d): %s\n", 00485 buflen, strerror(errno)); 00486 return NULL; 00487 } 00488 memset(buf+i, 0, buflen-i); 00489 00490 while (i < buflen) { 00491 r = read(fd, buf+i, 1); 00492 if (r < 0 && errno != EINTR) { 00493 /* we should do something with the data */ 00494 acpid_log("ERR: read(): %s\n", 00495 strerror(errno)); 00496 return NULL; 00497 } else if (r == 0) { 00498 /* signal this in an almost standard way */ 00499 errno = EPIPE; 00500 return NULL; 00501 } else if (r == 1) { 00502 /* scan for a newline */ 00503 if (buf[i] == '\n') { 00504 searching = 0; 00505 buf[i] = '\0'; 00506 break; 00507 } 00508 i++; 00509 } 00510 } 00511 if (buflen >= MAX_BUFLEN) { 00512 break; 00513 } 00514 buflen *= 2; 00515 } 00516 00517 return buf; 00518 }
|
|
|
Definition at line 442 of file acpid.c. References acpid_cleanup_rules(), acpid_log(), acpid_read_conf(), and confdir. Referenced by main(). 00443 { 00444 acpid_log("reloading configuration\n"); 00445 acpid_cleanup_rules(); 00446 acpid_read_conf(confdir); 00447 }
|
|
|
Definition at line 48 of file acpid.c. Referenced by acpid_cleanup_rules(), acpid_handle_event(), handle_cmdline(), lock_rules(), main(), parse_cmd(), parse_file(), safe_write(), and unlock_rules(). |
|
|
Definition at line 51 of file acpid.c. Referenced by handle_cmdline(), main(), and reload_conf(). |
|
|
Definition at line 53 of file acpid.c. Referenced by handle_cmdline(), and main(). |
|
|
Definition at line 58 of file acpid.c. Referenced by handle_cmdline(), and main(). |
|
|
Definition at line 52 of file acpid.c. Referenced by handle_cmdline(), and open_logs(). |
|
|
Definition at line 55 of file acpid.c. Referenced by handle_cmdline(), and main(). |
|
|
|
|
|
|
|
|
Definition at line 56 of file acpid.c. Referenced by handle_cmdline(), and main(). |
|
|
Definition at line 57 of file acpid.c. Referenced by handle_cmdline(), and main(). |