#include <unistd.h>
#include <strings.h>
#include <limits.h>
#include <dlfcn.h>
#include "_conv.h"
#include "lddstub_msg.h"
static int
originlddstub(char *buffer, const char *orgfile)
{
int len;
if (dlinfo(RTLD_SELF, RTLD_DI_ORIGIN, (void *)buffer) == -1)
return (-1);
if (strlcat(buffer, orgfile, PATH_MAX) >= PATH_MAX)
return (-1);
if ((len = resolvepath(buffer, buffer, (PATH_MAX - 1))) == -1)
return (-1);
buffer[len] = '\0';
if (access(buffer, X_OK) == -1)
return (-1);
return (1);
}
static char orgstub[PATH_MAX], orgstub64[PATH_MAX];
static int orgflag, orgflag64;
const char *
conv_lddstub(int class)
{
const char *stub;
if (class == ELFCLASS32)
stub = MSG_ORIG(MSG_PTH_LDDSTUB);
else
stub = MSG_ORIG(MSG_PTH_LDDSTUB_64);
if (geteuid()) {
if ((class == ELFCLASS32) && (orgflag != -1)) {
if (orgflag == 0) {
if ((orgflag = originlddstub(orgstub,
#ifdef _LP64
MSG_ORIG(MSG_ORG_64LDD_32STUB))) == -1)
#else
MSG_ORIG(MSG_ORG_32LDD_32STUB))) == -1)
#endif
return (stub);
}
stub = (const char *)orgstub;
}
if ((class == ELFCLASS64) && (orgflag64 != -1)) {
if (orgflag64 == 0) {
if ((orgflag64 = originlddstub(orgstub64,
#ifdef _LP64
MSG_ORIG(MSG_ORG_64LDD_64STUB))) == -1)
#else
MSG_ORIG(MSG_ORG_32LDD_64STUB))) == -1)
#endif
return (stub);
}
stub = (const char *)orgstub64;
}
}
return (stub);
}