Siddhesh Poyarekar 17b00fb
#include <sys/types.h>
Siddhesh Poyarekar 17b00fb
#include <sys/wait.h>
Siddhesh Poyarekar 17b00fb
#include <stdio.h>
Siddhesh Poyarekar 17b00fb
#include <errno.h>
Siddhesh Poyarekar 17b00fb
#include <unistd.h>
Siddhesh Poyarekar 17b00fb
#include <sys/time.h>
Siddhesh Poyarekar 17b00fb
#include <dirent.h>
Siddhesh Poyarekar 17b00fb
#include <stddef.h>
Siddhesh Poyarekar 17b00fb
#include <fcntl.h>
Siddhesh Poyarekar 17b00fb
#include <string.h>
Siddhesh Poyarekar 17b00fb
#include <sys/stat.h>
Siddhesh Poyarekar 17b00fb
#include <elf.h>
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
#define verbose_exec(failcode, path...) \
Siddhesh Poyarekar 17b00fb
  do							\
Siddhesh Poyarekar 17b00fb
    {							\
Siddhesh Poyarekar 17b00fb
      char *const arr[] = { path, NULL };		\
Siddhesh Poyarekar 17b00fb
      vexec (failcode, arr);				\
Siddhesh Poyarekar 17b00fb
    } while (0)
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
__attribute__((noinline)) void vexec (int failcode, char *const path[]);
Siddhesh Poyarekar 17b00fb
__attribute__((noinline)) void says (const char *str);
Siddhesh Poyarekar 17b00fb
__attribute__((noinline)) void sayn (long num);
Siddhesh Poyarekar 17b00fb
__attribute__((noinline)) void message (char *const path[]);
Siddhesh Poyarekar 17b00fb
__attribute__((noinline)) int check_elf (const char *name);
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
#ifdef __i386__
Siddhesh Poyarekar 17b00fb
static int
Siddhesh Poyarekar 17b00fb
is_ia64 (void)
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  unsigned int fl1, fl2;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* See if we can use cpuid.  */
Siddhesh Poyarekar 17b00fb
  __asm__ ("pushfl; pushfl; popl %0; movl %0,%1; xorl %2,%0;"
Siddhesh Poyarekar 17b00fb
	   "pushl %0; popfl; pushfl; popl %0; popfl"
Siddhesh Poyarekar 17b00fb
	   : "=&r" (fl1), "=&r" (fl2)
Siddhesh Poyarekar 17b00fb
	   : "i" (0x00200000));
Siddhesh Poyarekar 17b00fb
  if (((fl1 ^ fl2) & 0x00200000) == 0)
Siddhesh Poyarekar 17b00fb
    return 0;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Host supports cpuid.  See if cpuid gives capabilities, try
Siddhesh Poyarekar 17b00fb
     CPUID(0).  Preserve %ebx and %ecx; cpuid insn clobbers these, we
Siddhesh Poyarekar 17b00fb
     don't need their CPUID values here, and %ebx may be the PIC
Siddhesh Poyarekar 17b00fb
     register.  */
Siddhesh Poyarekar 17b00fb
  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
Siddhesh Poyarekar 17b00fb
	   : "=a" (fl1) : "0" (0) : "edx", "cc");
Siddhesh Poyarekar 17b00fb
  if (fl1 == 0)
Siddhesh Poyarekar 17b00fb
    return 0;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Invoke CPUID(1), return %edx; caller can examine bits to
Siddhesh Poyarekar 17b00fb
     determine what's supported.  */
Siddhesh Poyarekar 17b00fb
  __asm__ ("pushl %%ecx; pushl %%ebx; cpuid; popl %%ebx; popl %%ecx"
Siddhesh Poyarekar 17b00fb
	   : "=d" (fl2), "=a" (fl1) : "1" (1) : "cc");
Siddhesh Poyarekar 17b00fb
  return (fl2 & (1 << 30)) != 0;
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
#else
Siddhesh Poyarekar 17b00fb
#define is_ia64() 0
Siddhesh Poyarekar 17b00fb
#endif
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
int
Siddhesh Poyarekar 17b00fb
main (void)
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  struct stat statbuf;
Siddhesh Poyarekar 17b00fb
  char initpath[256];
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  char buffer[4096];
Siddhesh Poyarekar 17b00fb
  struct pref {
Siddhesh Poyarekar 17b00fb
    char *p;
Siddhesh Poyarekar 17b00fb
    int len;
Siddhesh Poyarekar 17b00fb
  } prefix[] = { { "libc-", 5 }, { "libm-", 5 },
Siddhesh Poyarekar 17b00fb
		 { "librt-", 6 }, { "libpthread-", 11 },
Siddhesh Poyarekar 17b00fb
		 { "librtkaio-", 10 }, { "libthread_db-", 13 } };
Siddhesh Poyarekar 17b00fb
  int i, j, fd;
Siddhesh Poyarekar 17b00fb
  off_t base;
Siddhesh Poyarekar 17b00fb
  ssize_t ret;
Siddhesh Poyarekar 17b00fb
#ifdef __i386__
Siddhesh Poyarekar 17b00fb
  const char *remove_dirs[] = { "/lib/tls", "/lib/i686", "/lib/tls/i486", "/lib/tls/i586", "/lib/tls/i686" };
Siddhesh Poyarekar 17b00fb
#else
Siddhesh Poyarekar 17b00fb
#ifndef LIBTLS
Siddhesh Poyarekar 17b00fb
#define LIBTLS "/lib/tls"
Siddhesh Poyarekar 17b00fb
#endif
Siddhesh Poyarekar 17b00fb
  const char *remove_dirs[] = { LIBTLS };
Siddhesh Poyarekar 17b00fb
#endif
Siddhesh Poyarekar 17b00fb
  for (j = 0; j < sizeof (remove_dirs) / sizeof (remove_dirs[0]); ++j)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      size_t rmlen = strlen (remove_dirs[j]);
Siddhesh Poyarekar 17b00fb
      fd = open (remove_dirs[j], O_RDONLY);
Siddhesh Poyarekar 17b00fb
      if (fd >= 0
Siddhesh Poyarekar 17b00fb
	  && (ret = getdirentries (fd, buffer, sizeof (buffer), &base))
Siddhesh Poyarekar 17b00fb
	     >= (ssize_t) offsetof (struct dirent, d_name))
Siddhesh Poyarekar 17b00fb
	{
Siddhesh Poyarekar 17b00fb
	  for (base = 0; base + offsetof (struct dirent, d_name) < ret; )
Siddhesh Poyarekar 17b00fb
	    {
Siddhesh Poyarekar 17b00fb
	      struct dirent *d = (struct dirent *) (buffer + base);
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
	      for (i = 0; i < sizeof (prefix) / sizeof (prefix[0]); i++)
Siddhesh Poyarekar 17b00fb
		if (! strncmp (d->d_name, prefix[i].p, prefix[i].len))
Siddhesh Poyarekar 17b00fb
		  {
Siddhesh Poyarekar 17b00fb
		    char *p = d->d_name + prefix[i].len;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
		    while (*p == '.' || (*p >= '0' && *p <= '9')) p++;
Siddhesh Poyarekar 17b00fb
		    if (p[0] == 's' && p[1] == 'o' && p[2] == '\0'
Siddhesh Poyarekar 17b00fb
			&& p + 3 - d->d_name
Siddhesh Poyarekar 17b00fb
			   < sizeof (initpath) - rmlen - 1)
Siddhesh Poyarekar 17b00fb
		      {
Siddhesh Poyarekar 17b00fb
			memcpy (initpath, remove_dirs[j], rmlen);
Siddhesh Poyarekar 17b00fb
			initpath[rmlen] = '/';
Siddhesh Poyarekar 17b00fb
			strcpy (initpath + rmlen + 1, d->d_name);
Siddhesh Poyarekar 17b00fb
			unlink (initpath);
Siddhesh Poyarekar 17b00fb
			break;
Siddhesh Poyarekar 17b00fb
		      }
Siddhesh Poyarekar 17b00fb
		  }
Siddhesh Poyarekar 17b00fb
	      base += d->d_reclen;
Siddhesh Poyarekar 17b00fb
	    }
Siddhesh Poyarekar 17b00fb
	  close (fd);
Siddhesh Poyarekar 17b00fb
	}
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  int ldsocfd = open (LD_SO_CONF, O_RDONLY);
Siddhesh Poyarekar 17b00fb
  struct stat ldsocst;
Siddhesh Poyarekar 17b00fb
  if (ldsocfd >= 0 && fstat (ldsocfd, &ldsocst) >= 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      char p[ldsocst.st_size + 1];
Siddhesh Poyarekar 17b00fb
      if (read (ldsocfd, p, ldsocst.st_size) == ldsocst.st_size)
Siddhesh Poyarekar 17b00fb
	{
Siddhesh Poyarekar 17b00fb
	  p[ldsocst.st_size] = '\0';
Siddhesh Poyarekar 17b00fb
	  if (strstr (p, "include ld.so.conf.d/*.conf") == NULL)
Siddhesh Poyarekar 17b00fb
	    {
Siddhesh Poyarekar 17b00fb
	      close (ldsocfd);
Siddhesh Poyarekar 17b00fb
	      ldsocfd = open (LD_SO_CONF, O_WRONLY | O_TRUNC);
Siddhesh Poyarekar 17b00fb
	      if (ldsocfd >= 0)
Siddhesh Poyarekar 17b00fb
		{
Siddhesh Poyarekar 17b00fb
		  size_t slen = strlen ("include ld.so.conf.d/*.conf\n");
Siddhesh Poyarekar 17b00fb
		  if (write (ldsocfd, "include ld.so.conf.d/*.conf\n", slen)
Siddhesh Poyarekar 17b00fb
		      != slen
Siddhesh Poyarekar 17b00fb
		      || write (ldsocfd, p, ldsocst.st_size) != ldsocst.st_size)
Siddhesh Poyarekar 17b00fb
		    _exit (109);
Siddhesh Poyarekar 17b00fb
		}
Siddhesh Poyarekar 17b00fb
	    }
Siddhesh Poyarekar 17b00fb
	}
Siddhesh Poyarekar 17b00fb
      if (ldsocfd >= 0)
Siddhesh Poyarekar 17b00fb
	close (ldsocfd);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* If installing bi-arch glibc, rpm sometimes doesn't unpack all files
Siddhesh Poyarekar 17b00fb
     before running one of the lib's %post scriptlet.  /sbin/ldconfig will
Siddhesh Poyarekar 17b00fb
     then be run by the other arch's %post.  */
Siddhesh Poyarekar 17b00fb
  if (! access ("/sbin/ldconfig", X_OK))
Siddhesh Poyarekar 17b00fb
    verbose_exec (110, "/sbin/ldconfig", "/sbin/ldconfig");
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  if (! utimes (GCONV_MODULES_DIR "/gconv-modules.cache", NULL))
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
#ifndef ICONVCONFIG
Siddhesh Poyarekar 17b00fb
#define ICONVCONFIG "/usr/sbin/iconvconfig"
Siddhesh Poyarekar 17b00fb
#endif
Carlos O'Donell 0457f64
      char *iconv_cache = GCONV_MODULES_DIR"/gconv-modules.cache";
Carlos O'Donell 0457f64
      char *iconv_dir = GCONV_MODULES_DIR;
Siddhesh Poyarekar 17b00fb
      if (is_ia64 ())
Siddhesh Poyarekar 17b00fb
	{
Siddhesh Poyarekar 17b00fb
	  iconv_cache = "/emul/ia32-linux"GCONV_MODULES_DIR"/gconv-modules.cache";
Siddhesh Poyarekar 17b00fb
	  iconv_dir = "/emul/ia32-linux"GCONV_MODULES_DIR;
Siddhesh Poyarekar 17b00fb
	}
Siddhesh Poyarekar 17b00fb
      verbose_exec (113, ICONVCONFIG, "/usr/sbin/iconvconfig",
Siddhesh Poyarekar 17b00fb
		    "-o", iconv_cache,
Siddhesh Poyarekar 17b00fb
		    "--nostdlib", iconv_dir);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Check if telinit is available and either SysVInit fifo,
Siddhesh Poyarekar 17b00fb
     or upstart telinit.  */
Siddhesh Poyarekar 17b00fb
  if (access ("/sbin/telinit", X_OK)
Siddhesh Poyarekar 17b00fb
      || ((!!access ("/dev/initctl", F_OK))
Siddhesh Poyarekar 17b00fb
	  ^ !access ("/sbin/initctl", X_OK)))
Siddhesh Poyarekar 17b00fb
    _exit (0);
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Check if we are not inside of some chroot, because we'd just
Siddhesh Poyarekar 17b00fb
     timeout and leave /etc/initrunlvl.
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
     On more modern systems this test is not sufficient to detect
Siddhesh Poyarekar 17b00fb
     if we're in a chroot.  */
Siddhesh Poyarekar 17b00fb
  if (readlink ("/proc/1/exe", initpath, 256) <= 0 ||
Siddhesh Poyarekar 17b00fb
      readlink ("/proc/1/root", initpath, 256) <= 0)
Siddhesh Poyarekar 17b00fb
    _exit (0);
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Here's another well known way to detect chroot, at least on an
Siddhesh Poyarekar 17b00fb
     ext and xfs filesystems and assuming nothing mounted on the chroot's
Siddhesh Poyarekar 17b00fb
     root. */
Siddhesh Poyarekar 17b00fb
  if (stat ("/", &statbuf) != 0
Siddhesh Poyarekar 17b00fb
      || (statbuf.st_ino != 2
Siddhesh Poyarekar 17b00fb
	  && statbuf.st_ino != 128))
Siddhesh Poyarekar 17b00fb
    _exit (0);
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  if (check_elf ("/proc/1/exe"))
Siddhesh Poyarekar 17b00fb
    verbose_exec (116, "/sbin/telinit", "/sbin/telinit", "u");
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  /* Check if we can safely condrestart sshd.  */
Siddhesh Poyarekar 17b00fb
  if (access ("/sbin/service", X_OK) == 0
Siddhesh Poyarekar 17b00fb
      && access ("/usr/sbin/sshd", X_OK) == 0
Siddhesh Poyarekar 17b00fb
      && access ("/etc/rc.d/init.d/sshd", X_OK) == 0
Siddhesh Poyarekar 17b00fb
      && access ("/bin/bash", X_OK) == 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      if (check_elf ("/usr/sbin/sshd"))
Siddhesh Poyarekar 17b00fb
	verbose_exec (-121, "/sbin/service", "/sbin/service", "sshd", "condrestart");
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  _exit(0);
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
void
Siddhesh Poyarekar 17b00fb
vexec (int failcode, char *const path[])
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  pid_t pid;
Siddhesh Poyarekar 17b00fb
  int status, save_errno;
Siddhesh Poyarekar 17b00fb
  int devnull = 0;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  if (failcode < 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      devnull = 1;
Siddhesh Poyarekar 17b00fb
      failcode = -failcode;
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
  pid = vfork ();
Siddhesh Poyarekar 17b00fb
  if (pid == 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      int fd;
Siddhesh Poyarekar 17b00fb
      if (devnull && (fd = open ("/dev/null", O_WRONLY)) >= 0)
Siddhesh Poyarekar 17b00fb
	{
Siddhesh Poyarekar 17b00fb
	  dup2 (fd, 1);
Siddhesh Poyarekar 17b00fb
	  dup2 (fd, 2);
Siddhesh Poyarekar 17b00fb
	  close (fd);
Siddhesh Poyarekar 17b00fb
	}
Siddhesh Poyarekar 17b00fb
      execv (path[0], path + 1);
Siddhesh Poyarekar 17b00fb
      save_errno = errno;
Siddhesh Poyarekar 17b00fb
      message (path);
Siddhesh Poyarekar 17b00fb
      says (" exec failed with errno ");
Siddhesh Poyarekar 17b00fb
      sayn (save_errno);
Siddhesh Poyarekar 17b00fb
      says ("\n");
Siddhesh Poyarekar 17b00fb
      _exit (failcode);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
  else if (pid < 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      save_errno = errno;
Siddhesh Poyarekar 17b00fb
      message (path);
Siddhesh Poyarekar 17b00fb
      says (" fork failed with errno ");
Siddhesh Poyarekar 17b00fb
      sayn (save_errno);
Siddhesh Poyarekar 17b00fb
      says ("\n");
Siddhesh Poyarekar 17b00fb
      _exit (failcode + 1);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
  if (waitpid (0, &status, 0) != pid || !WIFEXITED (status))
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      message (path);
Siddhesh Poyarekar 17b00fb
      says (" child terminated abnormally\n");
Siddhesh Poyarekar 17b00fb
      _exit (failcode + 2);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
  if (WEXITSTATUS (status))
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      message (path);
Siddhesh Poyarekar 17b00fb
      says (" child exited with exit code ");
Siddhesh Poyarekar 17b00fb
      sayn (WEXITSTATUS (status));
Siddhesh Poyarekar 17b00fb
      says ("\n");
Siddhesh Poyarekar 17b00fb
      _exit (WEXITSTATUS (status));
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
void
Siddhesh Poyarekar 17b00fb
says (const char *str)
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  write (1, str, strlen (str));
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
void
Siddhesh Poyarekar 17b00fb
sayn (long num)
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  char string[sizeof (long) * 3 + 1];
Siddhesh Poyarekar 17b00fb
  char *p = string + sizeof (string) - 1;
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  *p = '\0';
Siddhesh Poyarekar 17b00fb
  if (num == 0)
Siddhesh Poyarekar 17b00fb
    *--p = '0';
Siddhesh Poyarekar 17b00fb
  else
Siddhesh Poyarekar 17b00fb
    while (num)
Siddhesh Poyarekar 17b00fb
      {
Siddhesh Poyarekar 17b00fb
	*--p = '0' + num % 10;
Siddhesh Poyarekar 17b00fb
	num = num / 10;
Siddhesh Poyarekar 17b00fb
      }
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
  says (p);
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
void
Siddhesh Poyarekar 17b00fb
message (char *const path[])
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  says ("/usr/sbin/glibc_post_upgrade: While trying to execute ");
Siddhesh Poyarekar 17b00fb
  says (path[0]);
Siddhesh Poyarekar 17b00fb
}
Siddhesh Poyarekar 17b00fb
Siddhesh Poyarekar 17b00fb
int
Siddhesh Poyarekar 17b00fb
check_elf (const char *name)
Siddhesh Poyarekar 17b00fb
{
Siddhesh Poyarekar 17b00fb
  /* Play safe, if we can't open or read, assume it might be
Siddhesh Poyarekar 17b00fb
     ELF for the current arch.  */
Siddhesh Poyarekar 17b00fb
  int ret = 1;
Siddhesh Poyarekar 17b00fb
  int fd = open (name, O_RDONLY);
Siddhesh Poyarekar 17b00fb
  if (fd >= 0)
Siddhesh Poyarekar 17b00fb
    {
Siddhesh Poyarekar 17b00fb
      Elf32_Ehdr ehdr;
Siddhesh Poyarekar 17b00fb
      if (read (fd, &ehdr, offsetof (Elf32_Ehdr, e_version))
Siddhesh Poyarekar 17b00fb
	  == offsetof (Elf32_Ehdr, e_version))
Siddhesh Poyarekar 17b00fb
	{
Siddhesh Poyarekar 17b00fb
	  ret = 0;
Siddhesh Poyarekar 17b00fb
	  if (ehdr.e_ident[EI_CLASS]
Siddhesh Poyarekar 17b00fb
	      == (sizeof (long) == 8 ? ELFCLASS64 : ELFCLASS32))
Siddhesh Poyarekar 17b00fb
	    {
Siddhesh Poyarekar 17b00fb
#if defined __i386__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_386;
Siddhesh Poyarekar 17b00fb
#elif defined __x86_64__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_X86_64;
Siddhesh Poyarekar 17b00fb
#elif defined __ia64__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_IA_64;
Siddhesh Poyarekar 17b00fb
#elif defined __powerpc64__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_PPC64;
Siddhesh Poyarekar 17b00fb
#elif defined __powerpc__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_PPC;
Siddhesh Poyarekar 17b00fb
#elif defined __s390__ || defined __s390x__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_S390;
Siddhesh Poyarekar 17b00fb
#elif defined __x86_64__
Siddhesh Poyarekar 17b00fb
	      ret = ehdr.e_machine == EM_X86_64;
Siddhesh Poyarekar 17b00fb
#elif defined __sparc__
Siddhesh Poyarekar 17b00fb
	      if (sizeof (long) == 8)
Siddhesh Poyarekar 17b00fb
		ret = ehdr.e_machine == EM_SPARCV9;
Siddhesh Poyarekar 17b00fb
	      else
Siddhesh Poyarekar 17b00fb
		ret = (ehdr.e_machine == EM_SPARC
Siddhesh Poyarekar 17b00fb
		       || ehdr.e_machine == EM_SPARC32PLUS);
Siddhesh Poyarekar 17b00fb
#else
Siddhesh Poyarekar 17b00fb
	      ret = 1;
Siddhesh Poyarekar 17b00fb
#endif
Siddhesh Poyarekar 17b00fb
	    }
Siddhesh Poyarekar 17b00fb
	}
Siddhesh Poyarekar 17b00fb
      close (fd);
Siddhesh Poyarekar 17b00fb
    }
Siddhesh Poyarekar 17b00fb
  return ret;
Siddhesh Poyarekar 17b00fb
}