halt.c 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * Poweroff reboot and halt, oh my.
  4. *
  5. * Copyright 2006 by Rob Landley <rob@landley.net>
  6. *
  7. * Licensed under GPL version 2, see file LICENSE in this tarball for details.
  8. */
  9. #include "libbb.h"
  10. #include <sys/reboot.h>
  11. #if ENABLE_FEATURE_WTMP
  12. #include <sys/utsname.h>
  13. #include <utmp.h>
  14. #endif
  15. int halt_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  16. int halt_main(int argc ATTRIBUTE_UNUSED, char **argv)
  17. {
  18. static const int magic[] = {
  19. #ifdef RB_HALT_SYSTEM
  20. RB_HALT_SYSTEM,
  21. #elif defined RB_HALT
  22. RB_HALT,
  23. #endif
  24. #ifdef RB_POWER_OFF
  25. RB_POWER_OFF,
  26. #elif defined RB_POWERDOWN
  27. RB_POWERDOWN,
  28. #endif
  29. RB_AUTOBOOT
  30. };
  31. static const smallint signals[] = { SIGUSR1, SIGUSR2, SIGTERM };
  32. int delay = 0;
  33. int which, flags, rc = 1;
  34. #if ENABLE_FEATURE_WTMP
  35. struct utmp utmp;
  36. struct timeval tv;
  37. struct utsname uts;
  38. #endif
  39. /* Figure out which applet we're running */
  40. for (which = 0; "hpr"[which] != *applet_name; which++)
  41. continue;
  42. /* Parse and handle arguments */
  43. opt_complementary = "d+"; /* -d N */
  44. flags = getopt32(argv, "d:nfw", &delay);
  45. sleep(delay);
  46. #if ENABLE_FEATURE_WTMP
  47. if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
  48. close(creat(bb_path_wtmp_file, 0664));
  49. }
  50. memset(&utmp, 0, sizeof(utmp));
  51. gettimeofday(&tv, NULL);
  52. utmp.ut_tv.tv_sec = tv.tv_sec;
  53. utmp.ut_tv.tv_usec = tv.tv_usec;
  54. safe_strncpy(utmp.ut_user, "shutdown", UT_NAMESIZE);
  55. utmp.ut_type = RUN_LVL;
  56. safe_strncpy(utmp.ut_id, "~~", sizeof(utmp.ut_id));
  57. safe_strncpy(utmp.ut_line, "~~", UT_LINESIZE);
  58. if (uname(&uts) == 0)
  59. safe_strncpy(utmp.ut_host, uts.release, sizeof(utmp.ut_host));
  60. updwtmp(bb_path_wtmp_file, &utmp);
  61. #endif /* !ENABLE_FEATURE_WTMP */
  62. if (flags & 8) /* -w */
  63. return 0;
  64. if (!(flags & 2)) /* no -n */
  65. sync();
  66. /* Perform action. */
  67. if (ENABLE_INIT && !(flags & 4)) {
  68. if (ENABLE_FEATURE_INITRD) {
  69. pid_t *pidlist = find_pid_by_name("linuxrc");
  70. if (pidlist[0] > 0)
  71. rc = kill(pidlist[0], signals[which]);
  72. if (ENABLE_FEATURE_CLEAN_UP)
  73. free(pidlist);
  74. }
  75. if (rc)
  76. rc = kill(1, signals[which]);
  77. } else
  78. rc = reboot(magic[which]);
  79. if (rc)
  80. bb_error_msg("no");
  81. return rc;
  82. }