#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <sys/time.h>
#include <dirent.h>
#include <stddef.h>
#include <fcntl.h>
#include <string.h>

int main(void)
{
  pid_t pid;
  int status;
  char initpath[256];

  pid = vfork ();
  if (pid == 0)
    {
      execl ("/sbin/ldconfig", "/sbin/ldconfig", NULL);
      _exit (110);
    }
  else if (pid < 0)
    _exit (111);
  if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
    _exit (112);
  if (WEXITSTATUS (status))
    _exit (WEXITSTATUS (status));

  if (! utimes (GCONV_MODULES_CACHE, NULL))
    {
      pid = vfork ();
      if (pid == 0)
	{
	  execl ("/usr/sbin/iconvconfig", "/usr/sbin/iconvconfig", NULL);
	  _exit (113);
	}
      else if (pid < 0)
	_exit (114);
      if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
	_exit (115);
      if (WEXITSTATUS (status))
	_exit (WEXITSTATUS (status));
    }

  /* Check if telinit is available and the init fifo as well.  */
  if (access ("/sbin/telinit", X_OK) || access ("/dev/initctl", F_OK))
    _exit (0);
  /* Check if we are not inside of some chroot, because we'd just
     timeout and leave /etc/initrunlvl.  */
  if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
      readlink ("/proc/1/root", initpath, 256) <= 0)
    _exit (0);

  pid = vfork ();
  if (pid == 0)
    {
      execl ("/sbin/telinit", "/sbin/telinit", "u", NULL);
      _exit (116);
    }
  else if (pid < 0)
    _exit (117);
  if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
    _exit (118);

  /* Check if we can safely condrestart sshd.  */
  if (access ("/sbin/service", X_OK) == 0
      && access ("/usr/sbin/sshd", X_OK) == 0
      && access ("/bin/bash", X_OK) == 0)
    {
      pid = vfork ();
      if (pid == 0)
	{
	  execl ("/sbin/service", "/sbin/service", "sshd", "condrestart", NULL);
	  _exit (119);
	}
      else if (pid < 0)
	_exit (120);
      if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
	_exit (121);
    }

  _exit(0);
}

int __libc_multiple_threads;
int __libc_enable_asynccancel (void) { return 0; }
void __libc_disable_asynccancel (int x) { }
void __libc_csu_init (void) { }
void __libc_csu_fini (void) { }
pid_t __fork (void) { return -1; }
char thr_buf[8192];

#ifndef __powerpc__
int __libc_start_main (int (*main) (void), int argc, char **argv,
		       void (*init) (void), void (*fini) (void),
		       void (*rtld_fini) (void), void * stack_end)
#else
struct startup_info
{
  void *sda_base;
  int (*main) (int, char **, char **, void *);
  int (*init) (int, char **, char **, void *);
  void (*fini) (void);
};

int __libc_start_main (int argc, char **ubp_av,
		       char **ubp_ev,
		       void *auxvec, void (*rtld_fini) (void),
		       struct startup_info *stinfo,
		       char **stack_on_entry)
#endif
{
#if defined __ia64__ || defined __powerpc64__
  register void *r13 __asm ("r13") = thr_buf + 4096;
  __asm ("" : : "r" (r13));
#elif defined __sparc__
  register void *g6 __asm ("g6") = thr_buf + 4096;
  register void *g7 __asm ("g7") = thr_buf + 4096;
  __asm ("" : : "r" (g6), "r" (g7));
#elif defined __s390__ && !defined __s390x__
  __asm ("sar %%a0,%0" : : "d" (thr_buf + 4096));
#elif defined __s390x__
  __asm ("sar %%a1,%0; srlg 0,%0,32; sar %%a0,0" : : "d" (thr_buf + 4096) : "0");
#elif defined __powerpc__ && !defined __powerpc64__
  register void *r2 __asm ("r2") = thr_buf + 4096;
  __asm ("" : : "r" (r2));
#endif
  main();
  return 0;
}
