- halt's -w depends on FEATURE_WTMP (Vladimir Dronnikov)
[oweals/busybox.git] / init / halt.c
index d5c22a8ac5f72572b5d7e2f13505cdea9f0e16cd..42b9edc08f849d364b8b68a12f109d7eb204dd07 100644 (file)
@@ -7,40 +7,75 @@
  * Licensed under GPL version 2, see file LICENSE in this tarball for details.
  */
 
-#include "busybox.h"
+#include "libbb.h"
 #include <sys/reboot.h>
 
-int halt_main(int argc, char *argv[]);
-int halt_main(int argc, char *argv[])
+#if ENABLE_FEATURE_WTMP
+#include <sys/utsname.h>
+#include <utmp.h>
+#endif
+
+int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
+int halt_main(int argc UNUSED_PARAM, char **argv)
 {
        static const int magic[] = {
 #ifdef RB_HALT_SYSTEM
-RB_HALT_SYSTEM,
+               RB_HALT_SYSTEM,
 #elif defined RB_HALT
-RB_HALT,
+               RB_HALT,
 #endif
 #ifdef RB_POWER_OFF
-RB_POWER_OFF,
+               RB_POWER_OFF,
 #elif defined RB_POWERDOWN
-RB_POWERDOWN,
+               RB_POWERDOWN,
 #endif
-RB_AUTOBOOT
+               RB_AUTOBOOT
        };
-       static const int signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
+       static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
 
-       char *delay;
-       int which, flags, rc = 1;
+       int delay = 0;
+       int which, flags, rc;
+#if ENABLE_FEATURE_WTMP
+       struct utmp utmp;
+       struct utsname uts;
+#endif
 
        /* Figure out which applet we're running */
-       for (which = 0; "hpr"[which] != *applet_name; which++);
+       for (which = 0; "hpr"[which] != *applet_name; which++)
+               continue;
 
        /* Parse and handle arguments */
-       flags = getopt32(argc, argv, "d:nf", &delay);
-       if (flags & 1) sleep(xatou(delay));
-       if (!(flags & 2)) sync();
+       opt_complementary = "d+"; /* -d N */
+       flags = getopt32(argv, "d:nf" USE_FEATURE_WTMP("w"), &delay);
+
+       sleep(delay);
+
+#if ENABLE_FEATURE_WTMP
+       if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
+               close(creat(bb_path_wtmp_file, 0664));
+       }
+       memset(&utmp, 0, sizeof(utmp));
+       utmp.ut_tv.tv_sec = time(NULL);
+       safe_strncpy(utmp.ut_user, "shutdown", UT_NAMESIZE);
+       utmp.ut_type = RUN_LVL;
+       safe_strncpy(utmp.ut_id, "~~", sizeof(utmp.ut_id));
+       safe_strncpy(utmp.ut_line, "~~", UT_LINESIZE);
+       if (uname(&uts) == 0)
+               safe_strncpy(utmp.ut_host, uts.release, sizeof(utmp.ut_host));
+       updwtmp(bb_path_wtmp_file, &utmp);
+
+       if (flags & 8) /* -w */
+               return EXIT_SUCCESS;
+#endif /* !ENABLE_FEATURE_WTMP */
+
+       if (!(flags & 2)) /* no -n */
+               sync();
 
        /* Perform action. */
-       if (ENABLE_INIT && !(flags & 4)) {
+       rc = 1;
+       if (!(flags & 4)) { /* no -f */
+//TODO: I tend to think that signalling linuxrc is wrong
+// pity original author didn't comment on it...
                if (ENABLE_FEATURE_INITRD) {
                        pid_t *pidlist = find_pid_by_name("linuxrc");
                        if (pidlist[0] > 0)