int main(int argc, char *argv[]) { int pv = 0; char *p = strchr(argv[0], '/'); if (p) p++; else p = argv[0]; if (argc == 2 && strcmp(argv[1], "-f") == 0) { argc--; pv = AD_NOSYNC; } if (argc != 1) { write(2, argv[0], strlen(argv[0])); write(2, ": unexpected argument.\n", 21); exit(1); } /* shutdown does a polite shutdown */ if (strcmp(p, "shutdown") == 0) { if (telinit6()) exit(0); write(2, argv[0], strlen(argv[0])); write(2, ": unable to talk to init.\n", 24); } if (strcmp(p, "halt") == 0) uadmin(A_SHUTDOWN, pv, 0); else if (strcmp(p, "suspend") == 0) uadmin(A_SUSPEND, pv, 0); else uadmin(A_REBOOT, pv, 0); /* If we get here there was an error! */ perror(argv[0]); return 1; }
int main(int argc, char *argv[]) { char *p = strchr(argv[0], '/'); if (p) p++; else p = argv[0]; if (strcmp(p, "halt") == 0) uadmin(A_SHUTDOWN,0,0); else uadmin(A_REBOOT,0,0); /* If we get here there was an error! */ perror(argv[0]); }
/* * pm_check_suspend() - Check to see if suspend is supported/enabled * on this machine. * Ultimately, we would prefer to get the "default" suspend type from * a PM property or some other API, but for now, we know that STR is * only available on x86 and STD is only available on Sparc. It does * make this function quite easy, though. */ static int pm_check_suspend(void) { /* * Use the uadmin(2) "CHECK" command to see if suspend is supported */ return (uadmin(A_FREEZE, AD_CHECK_SUSPEND, 0)); }
/*ARGSUSED*/ static void power_button_monitor(void *arg) { struct pollfd pfd; int events, ret; if (ioctl(pb_fd, PB_BEGIN_MONITOR, NULL) == -1) { logerror("Failed to monitor the power button."); thr_exit((void *) 0); } pfd.fd = pb_fd; pfd.events = POLLIN; /*CONSTCOND*/ while (1) { if (poll(&pfd, 1, INFTIM) == -1) { logerror("Failed to poll for power button events."); thr_exit((void *) 0); } if (!(pfd.revents & POLLIN)) continue; /* * Monitor the power button, but only take action if * gnome-power-manager is not running. * * ret greater than 0 means could not find process. */ ret = system("/usr/bin/pgrep -fx gnome-power-manager"); if (ioctl(pfd.fd, PB_GET_EVENTS, &events) == -1) { logerror("Failed to get power button events."); thr_exit((void *) 0); } if ((ret > 0) && (events & PB_BUTTON_PRESS) && (poweroff(NULL, power_button_cmd) != 0)) { logerror("Power button is pressed, powering " "down the system!"); /* * Send SIGPWR signal to the init process to * shut down the system. */ if (kill(1, SIGPWR) == -1) (void) uadmin(A_SHUTDOWN, AD_POWEROFF, 0); } /* * Clear any power button event that has happened * meanwhile we were busy processing the last one. */ if (ioctl(pfd.fd, PB_GET_EVENTS, &events) == -1) { logerror("Failed to get power button events."); thr_exit((void *) 0); } } }
/*ARGSUSED*/ static void power_button_monitor(void *arg) { struct pollfd pfd; int events; if (ioctl(pb_fd, PB_BEGIN_MONITOR, NULL) == -1) { logerror("Failed to monitor the power button."); thr_exit((void *) 0); } pfd.fd = pb_fd; pfd.events = POLLIN; /*CONSTCOND*/ while (1) { if (poll(&pfd, 1, INFTIM) == -1) { logerror("Failed to poll for power button events."); thr_exit((void *) 0); } if (!(pfd.revents & POLLIN)) continue; if (ioctl(pfd.fd, PB_GET_EVENTS, &events) == -1) { logerror("Failed to get power button events."); thr_exit((void *) 0); } if ((events & PB_BUTTON_PRESS) && (poweroff(NULL, power_button_cmd) != 0)) { logerror("Power button is pressed, powering " "down the system!"); /* * Send SIGPWR signal to the init process to * shut down the system. */ if (kill(1, SIGPWR) == -1) (void) uadmin(A_SHUTDOWN, AD_POWEROFF, 0); } /* * Clear any power button event that has happened * meanwhile we were busy processing the last one. */ if (ioctl(pfd.fd, PB_GET_EVENTS, &events) == -1) { logerror("Failed to get power button events."); thr_exit((void *) 0); } } }
/* * Note that not all of BSD's semantics are supported. */ int reboot(int howto, char *bootargs) { int cmd = A_SHUTDOWN; int fcn = AD_BOOT; if (howto & RB_DUMP) cmd = A_DUMP; if (howto & RB_HALT) fcn = AD_HALT; else if (howto & RB_ASKNAME) fcn = AD_IBOOT; return (uadmin(cmd, fcn, (uintptr_t)bootargs)); }
/* * This entry point _should_ be the common entry to suspend. It is in * it's entirety here, but would be best moved to libpower when that * is available. */ static void pm_suspend(void) { int cprarg = AD_SUSPEND; enum adt_uadmin_fcn fcn_id = ADT_FCN; au_event_t event_id = ADT_uadmin_freeze; adt_event_data_t *event = NULL; /* event to be generated */ adt_session_data_t *ah = NULL; /* audit session handle */ /* * Does the user have permission to use this command? */ if (chkauthattr(AUTHNAME_SUSPEND, user) != 1) { (void) printf(gettext("User %s does not have correct " "authorizations to suspend this machine.\n"), user); exit(1); } if (flags & LOWPOWER) { if (bringto_lowpower() == -1) { (void) printf(gettext("LowPower Failed\n")); exit(1); } } else if (flags & TEST) { /* * Test mode, do checks as if a real suspend, but * don't actually do the suspend. */ /* Check if suspend is supported */ if (pm_check_suspend() == -1) { suspend_error(errno); } (void) printf(gettext("TEST: Suspend would have been" " performed\n")); } else { /* Check if suspend is supported */ if (pm_check_suspend() == -1) { suspend_error(errno); } /* * We are about to suspend this machine, try and * lock the screen. We don't really care if this * succeeds or not, but that we actually tried. We * also know that we have sufficient privileges to * be here, so we lock the screen now, even if * suspend actually fails. * Note that garbage is sometimes displayed, and * we don't really care about it, so we toss all * text response. * it would also be good if there were another option * instead of launcing a file, as the disk might be * spun down if we are suspending due to idle. */ if (!(flags & NO_XLOCK)) { (void) system("/usr/bin/xdg-screensaver lock " " >/dev/null 2>&1"); } /* Time to do the actual deed! */ /* * Before we actually suspend, we need to audit and * "suspend" the audit files. */ /* set up audit session and event */ if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA) == 0) { if ((event = adt_alloc_event(ah, event_id)) != NULL) { event->adt_uadmin_freeze.fcn = fcn_id; event->adt_uadmin_freeze.mdep = NULL; if (adt_put_event(event, ADT_SUCCESS, 0) != 0) { (void) fprintf(stderr, gettext( "%s: can't put audit event\n"), argvl[0]); } else { wait_for_auqueue(); } } (void) change_audit_file(); } else { (void) fprintf(stderr, gettext( "%s: can't start audit session\n"), argvl[0]); } if (uadmin(A_FREEZE, cprarg, 0) != 0) { (void) printf(gettext("Suspend Failed\n")); if (flags & FORCE) { /* * Note, that if we actually poweroff, * that the poweroff function will handle * that audit trail, and the resume * trail is effectively done. */ pm_poweroff(); } else { /* suspend_error() will exit. */ suspend_error(errno); /* * Audit the suspend failure and * reuse the event, but don't create one * if we don't already have one. */ if (event != NULL) { (void) adt_put_event(event, ADT_FAILURE, 0); } } } /* * Write the thaw event. */ if (ah != NULL) { if ((event == NULL) && ((event = adt_alloc_event(ah, ADT_uadmin_thaw)) == NULL)) { (void) fprintf(stderr, gettext( "%s: can't allocate thaw audit event\n"), argvl[0]); } else { event->adt_uadmin_thaw.fcn = fcn_id; if (adt_put_event(event, ADT_SUCCESS, 0) != 0) { (void) fprintf(stderr, gettext( "%s: can't put thaw audit event\n"), argvl[0]); } (void) adt_free_event(event); } } } if ((no_tty ? 0 : 1) && !(flags & NO_XLOCK)) { pm_do_auth(ah); } (void) adt_end_session(ah); }