static void send_cmd(const char *cmd) { FILE *fifo; size_t ignored; if (do_dryrun) { einfo("Would send %s to init", cmd); return; } if (do_wtmp && (do_halt || do_kexec || do_reboot || do_poweroff)) log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); fifo = fopen(RC_INIT_FIFO, "w"); if (!fifo) { perror("fopen"); return; } ignored = fwrite(cmd, 1, strlen(cmd), fifo); if (ignored != strlen(cmd)) printf("Error writing to init fifo\n"); fclose(fifo); }
int main(int argc, char **argv) { char *ch = NULL; int opt; int cmd_count = 0; int hour = 0; int min = 0; int shutdown_delay = 0; struct sigaction sa; struct tm *lt; time_t tv; bool need_warning = false; char *msg = NULL; char *state = NULL; char *time_arg = NULL; FILE *fp; applet = basename_c(argv[0]); while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1) { switch (opt) { case 'c': do_cancel = true; cmd_count++; break; case 'd': do_wtmp = false; break; case 'D': do_dryrun = true; break; case 'H': do_halt = true; xasprintf(&state, "%s", "halt"); cmd_count++; break; case 'K': do_kexec = true; xasprintf(&state, "%s", "reboot"); cmd_count++; break; case 'p': do_poweroff = true; xasprintf(&state, "%s", "power off"); cmd_count++; break; case 'R': do_reexec = true; cmd_count++; break; case 'r': do_reboot = true; xasprintf(&state, "%s", "reboot"); cmd_count++; break; case 's': do_single = true; xasprintf(&state, "%s", "go down for maintenance"); cmd_count++; break; case 'w': do_wtmp_only = true; cmd_count++; break; case_RC_COMMON_GETOPT } } if (geteuid() != 0) eerrorx("%s: you must be root\n", applet); if (cmd_count != 1) { eerror("%s: %s\n", applet, exclusive); usage(EXIT_FAILURE); } if (do_cancel) { cancel_shutdown(); exit(EXIT_SUCCESS); } else if (do_reexec) { send_cmd("reexec"); exit(EXIT_SUCCESS); } else if (do_wtmp_only) { log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); exit(EXIT_SUCCESS); } if (optind >= argc) { eerror("%s: No shutdown time specified", applet); usage(EXIT_FAILURE); } time_arg = argv[optind]; if (*time_arg == '+') time_arg++; if (strcasecmp(time_arg, "now") == 0) strcpy(time_arg, "0"); for (ch=time_arg; *ch; ch++) if ((*ch < '0' || *ch > '9') && *ch != ':') { eerror("%s: invalid time %s", applet, time_arg); usage(EXIT_FAILURE); } if (strchr(time_arg, ':')) { if ((sscanf(time_arg, "%2d:%2d", &hour, &min) != 2) || (hour > 23) || (min > 59)) { eerror("%s: invalid time %s", applet, time_arg); usage(EXIT_FAILURE); } time(&tv); lt = localtime(&tv); shutdown_delay = (hour * 60 + min) - (lt->tm_hour * 60 + lt->tm_min); if (shutdown_delay < 0) shutdown_delay += 1440; } else { shutdown_delay = atoi(time_arg); } fp = fopen(shutdown_pid, "w"); if (!fp) eerrorx("%s: fopen `%s': %s", applet, shutdown_pid, strerror(errno)); fprintf(fp, "%d\n", getpid()); fclose(fp); openlog(applet, LOG_PID, LOG_DAEMON); memset(&sa, 0, sizeof(sa)); sa.sa_handler = stop_shutdown; sigemptyset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); while (shutdown_delay > 0) { need_warning = false; if (shutdown_delay > 180) need_warning = (shutdown_delay % 60 == 0); else if (shutdown_delay > 60) need_warning = (shutdown_delay % 30 == 0); else if (shutdown_delay > 10) need_warning = (shutdown_delay % 15 == 0); else need_warning = true; if (shutdown_delay <= 5) create_nologin(shutdown_delay); if (need_warning) { xasprintf(&msg, "\rThe system will %s in %d minutes\r\n", state, shutdown_delay); broadcast(msg); free(msg); } sleep_no_interrupt(60); shutdown_delay--; } xasprintf(&msg, "\rThe system will %s now\r\n", state); broadcast(msg); syslog(LOG_NOTICE, "The system will %s now", state); unlink(nologin_file); unlink(shutdown_pid); if (do_halt) send_cmd("halt"); else if (do_kexec) send_cmd("kexec"); else if (do_poweroff) send_cmd("poweroff"); else if (do_reboot) send_cmd("reboot"); else if (do_single) send_cmd("single"); return 0; }
int main(int argc, char **argv) { int opt; int cmd_count = 0; applet = basename_c(argv[0]); while ((opt = getopt_long(argc, argv, getoptstring, longopts, (int *) 0)) != -1) { switch (opt) { case 'd': do_wtmp = false; break; case 'D': do_dryrun = true; break; case 'H': do_halt = true; cmd_count++; break; case 'K': do_kexec = true; cmd_count++; break; case 'p': do_poweroff = true; cmd_count++; break; case 'R': do_reexec = true; cmd_count++; break; case 'r': do_reboot = true; cmd_count++; break; case 's': do_single = true; cmd_count++; break; case 'w': do_wtmp_only = true; cmd_count++; break; case_RC_COMMON_GETOPT } } if (geteuid() != 0 && ! do_dryrun) eerrorx("%s: you must be root\n", applet); if (cmd_count != 1) { eerror("%s: %s\n", applet, exclusive); usage(EXIT_FAILURE); } if (do_halt) send_cmd("halt"); else if (do_kexec) send_cmd("kexec"); else if (do_poweroff) send_cmd("poweroff"); else if (do_reboot) send_cmd("reboot"); else if (do_reexec) send_cmd("reexec"); else if (do_wtmp_only) log_wtmp("shutdown", "~~", 0, RUN_LVL, "~~"); else if (do_single) send_cmd("single"); return 0; }
static void sess_cleanup(int flags) { /* Clear the scoreboard entry. */ if (ServerType == SERVER_STANDALONE) { /* For standalone daemons, we only clear the scoreboard slot if we are * an exiting child process. */ if (!is_master) { if (pr_scoreboard_entry_del(TRUE) < 0 && errno != EINVAL && errno != ENOENT) { pr_log_debug(DEBUG1, "error deleting scoreboard entry: %s", strerror(errno)); } } } else if (ServerType == SERVER_INETD) { /* For inetd-spawned daemons, we always clear the scoreboard slot. */ if (pr_scoreboard_entry_del(TRUE) < 0 && errno != EINVAL && errno != ENOENT) { pr_log_debug(DEBUG1, "error deleting scoreboard entry: %s", strerror(errno)); } } /* If session.user is set, we have a valid login. */ if (session.user && session.wtmp_log) { const char *sess_ttyname; sess_ttyname = pr_session_get_ttyname(session.pool); log_wtmp(sess_ttyname, "", pr_netaddr_get_sess_remote_name(), pr_netaddr_get_sess_remote_addr()); } /* These are necessary in order that cleanups associated with these pools * (and their subpools) are properly run. */ if (session.d) { pr_inet_close(session.pool, session.d); session.d = NULL; } if (session.c) { pr_inet_close(session.pool, session.c); session.c = NULL; } /* Run all the exit handlers */ pr_event_generate("core.exit", NULL); if (!is_master || (ServerType == SERVER_INETD && !(flags & PR_SESS_END_FL_SYNTAX_CHECK))) { pr_log_pri(PR_LOG_INFO, "%s session closed.", pr_session_get_protocol(PR_SESS_PROTO_FL_LOGOUT)); } log_closesyslog(); }