halt.c 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  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 utsname uts;
  37. #endif
  38. /* Figure out which applet we're running */
  39. for (which = 0; "hpr"[which] != *applet_name; which++)
  40. continue;
  41. /* Parse and handle arguments */
  42. opt_complementary = "d+"; /* -d N */
  43. flags = getopt32(argv, "d:nfw", &delay);
  44. sleep(delay);
  45. #if ENABLE_FEATURE_WTMP
  46. if (access(bb_path_wtmp_file, R_OK|W_OK) == -1) {
  47. close(creat(bb_path_wtmp_file, 0664));
  48. }
  49. memset(&utmp, 0, sizeof(utmp));
  50. utmp.ut_tv.tv_sec = time(NULL);
  51. safe_strncpy(utmp.ut_user, "shutdown", UT_NAMESIZE);
  52. utmp.ut_type = RUN_LVL;
  53. safe_strncpy(utmp.ut_id, "~~", sizeof(utmp.ut_id));
  54. safe_strncpy(utmp.ut_line, "~~", UT_LINESIZE);
  55. if (uname(&uts) == 0)
  56. safe_strncpy(utmp.ut_host, uts.release, sizeof(utmp.ut_host));
  57. updwtmp(bb_path_wtmp_file, &utmp);
  58. #endif /* !ENABLE_FEATURE_WTMP */
  59. if (flags & 8) /* -w */
  60. return 0;
  61. if (!(flags & 2)) /* no -n */
  62. sync();
  63. /* Perform action. */
  64. if (ENABLE_INIT && !(flags & 4)) {
  65. if (ENABLE_FEATURE_INITRD) {
  66. pid_t *pidlist = find_pid_by_name("linuxrc");
  67. if (pidlist[0] > 0)
  68. rc = kill(pidlist[0], signals[which]);
  69. if (ENABLE_FEATURE_CLEAN_UP)
  70. free(pidlist);
  71. }
  72. if (rc)
  73. rc = kill(1, signals[which]);
  74. } else
  75. rc = reboot(magic[which]);
  76. if (rc)
  77. bb_error_msg("no");
  78. return rc;
  79. }