You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
132 lines
3.6 KiB
132 lines
3.6 KiB
/* |
|
* halt.c: A halt/poweroff/reboot wrapper for Artix Linux |
|
* Based on halt.c from void-runit |
|
* |
|
* Copyright (C) 2018 Muhammad Herdiansyah |
|
* (C) 2018 Artix Linux Developers |
|
* |
|
* To see the license terms of this program, see COPYING |
|
*/ |
|
|
|
#include <stdio.h> |
|
#include <stdlib.h> |
|
#include <unistd.h> |
|
#include <string.h> |
|
#include <err.h> |
|
#include <sys/reboot.h> |
|
|
|
extern char *__progname; |
|
|
|
typedef enum {NOOP, REBOOT, POWEROFF, WRITE_ONLY} action_type; |
|
typedef enum {OPENRC, RUNIT} initsys; |
|
|
|
const char* get_init() |
|
{ |
|
char *name = (char *)calloc(1024,sizeof(char)); |
|
if(name) { |
|
sprintf(name, "/proc/1/cmdline"); |
|
FILE *f = fopen(name, "r"); |
|
if (f) { |
|
size_t size; |
|
size = fread(name, sizeof(char), 1024, f); |
|
if (size > 0) { |
|
if ('\n' == name[size-1]) |
|
name[size-1]='\0'; |
|
} |
|
fclose(f); |
|
} |
|
} |
|
return name; |
|
} |
|
|
|
int main(int argc, char *argv[]) |
|
{ |
|
if (getuid() != 0) |
|
errx(1, "You must be root to do that!"); |
|
|
|
int do_sync = 1; |
|
int do_force = 0; |
|
int write_only = 0; |
|
int opt; |
|
action_type action = NOOP; |
|
initsys init; |
|
const char *initfile = get_init(); |
|
char openrc_options[50]; |
|
|
|
if (strcmp(initfile, "runit") == 0) |
|
init = RUNIT; |
|
else init = OPENRC; |
|
|
|
if (strcmp(__progname, "reboot") == 0) |
|
action = REBOOT; |
|
else if (strcmp(__progname, "halt") == 0 || strcmp(__progname, "poweroff") == 0 || strcmp(__progname, "shutdown") == 0) |
|
action = POWEROFF; |
|
else |
|
warnx("No default behavior, needs to be called as halt/reboot/poweroff/shutdown."); |
|
|
|
while ((opt = getopt(argc, argv, "dfhinw")) != -1) |
|
switch (opt) { |
|
case 'n': |
|
do_sync = 0; |
|
strcat(openrc_options, "--no-write"); |
|
break; |
|
case 'w': |
|
if (init == RUNIT) |
|
action = NOOP; |
|
else |
|
action = WRITE_ONLY; |
|
do_sync = 0; |
|
break; |
|
case 'd': |
|
strcat(openrc_options, "--no-write"); |
|
break; |
|
case 'h': |
|
case 'i': |
|
break; |
|
case 'f': |
|
do_force = 1; |
|
break; |
|
default: |
|
errx(1, "Usage: %s [-n] [-f]", __progname); |
|
} |
|
|
|
if (do_sync) |
|
sync(); |
|
|
|
switch (action) { |
|
case POWEROFF: |
|
if (do_force) |
|
reboot(RB_POWER_OFF); |
|
else |
|
switch (init) { |
|
case RUNIT: |
|
execl("/usr/bin/runit-init", "init", "0", (char*)0); |
|
break; |
|
case OPENRC: |
|
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--poweroff", "now", openrc_options, (char*)0); |
|
break; |
|
} |
|
err(1, "poweroff failed"); |
|
break; |
|
case REBOOT: |
|
if (do_force) |
|
reboot(RB_AUTOBOOT); |
|
else |
|
switch(init) { |
|
case RUNIT: |
|
execl("/usr/bin/runit-init", "init", "6", (char*)0); |
|
break; |
|
case OPENRC: |
|
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--reboot", "now", openrc_options, (char*)0); |
|
break; |
|
} |
|
err(1, "reboot failed"); |
|
break; |
|
case WRITE_ONLY: /* only applicable for OpenRC */ |
|
execl("/usr/bin/openrc-shutdown", "openrc-shutdown", "--write-only", (char*)0); |
|
case NOOP: |
|
break; |
|
} |
|
|
|
return 0; |
|
}
|
|
|