|
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 |
}
|