summaryrefslogtreecommitdiffstats
path: root/trunk/src/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/main.c')
-rw-r--r--trunk/src/main.c82
1 files changed, 76 insertions, 6 deletions
diff --git a/trunk/src/main.c b/trunk/src/main.c
index 144ce84..4678ba4 100644
--- a/trunk/src/main.c
+++ b/trunk/src/main.c
@@ -58,12 +58,14 @@ const char *ld_library_path;
const char *prelink_conf = PRELINK_CONF;
const char *prelink_cache = PRELINK_CACHE;
const char *undo_output;
+int noreexecinit;
+time_t initctime;
-const char *argp_program_version = "prelink 1.0";
+const char *argp_program_version = PRELINK_PROG PKGVERSION " 1.0";
-const char *argp_program_bug_address = "<jakub@redhat.com>";
+const char *argp_program_bug_address = REPORT_BUGS_TO;
-static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared libraries and programs";
+static char argp_doc[] = PRELINK_PROG " -- program to relocate and prelink ELF shared libraries and programs";
#define OPT_DYNAMIC_LINKER 0x80
#define OPT_LD_LIBRARY_PATH 0x81
@@ -77,6 +79,8 @@ static char argp_doc[] = "prelink -- program to relocate and prelink ELF shared
#define OPT_MD5 0x89
#define OPT_SHA 0x8a
#define OPT_COMPUTE_CHECKSUM 0x8b
+#define OPT_SYSROOT 0x8c
+#define OPT_RTLD 0x8d
static struct argp_option options[] = {
{"all", 'a', 0, 0, "Prelink all binaries" },
@@ -94,6 +98,7 @@ static struct argp_option options[] = {
{"quick", 'q', 0, 0, "Quick scan" },
{"random", 'R', 0, 0, "Choose random base for libraries" },
{"reloc-only", 'r', "BASE_ADDRESS", 0, "Relocate library to given address, don't prelink" },
+ {"root", OPT_SYSROOT, "ROOT_PATH", 0, "Prefix all paths with ROOT_PATH" },
{"undo", 'u', 0, 0, "Undo prelink" },
{"verbose", 'v', 0, 0, "Produce verbose output" },
{"verify", 'y', 0, 0, "Verify file consistency by undoing and redoing prelink and printing original to standard output" },
@@ -111,6 +116,8 @@ static struct argp_option options[] = {
{"mmap-region-end", OPT_MMAP_REG_END, "BASE_ADDRESS", OPTION_HIDDEN, "" },
{"seed", OPT_SEED, "SEED", OPTION_HIDDEN, "" },
{"compute-checksum", OPT_COMPUTE_CHECKSUM, 0, OPTION_HIDDEN, "" },
+ {"rtld", OPT_RTLD, "RTLD", OPTION_HIDDEN, "" },
+ {"init", 'i', 0, 0, "Do not re-execute init" },
{ 0 }
};
@@ -222,14 +229,39 @@ parse_opt (int key, char *arg, struct argp_state *state)
case OPT_COMPUTE_CHECKSUM:
compute_checksum = 1;
break;
+ case OPT_SYSROOT:
+ sysroot = arg;
+ break;
+ case OPT_RTLD:
+ prelink_rtld = arg;
+ break;
+ case 'i':
+ noreexecinit=1;
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
return 0;
}
+time_t get_ctime(const char *file) {
+ struct stat st;
+ if(stat(file,&st) == 0)
+ return st.st_ctime;
+ return 0;
+}
+
+void checkinit() {
+ if(initctime != get_ctime("/sbin/init")) {
+ printf("Executing /sbin/init U\n");
+ system("/sbin/init U");
+ }
+}
+
static struct argp argp = { options, parse_opt, "[FILES]", argp_doc };
+const char *prelink_rtld = NULL;
+
int
main (int argc, char *argv[])
{
@@ -237,9 +269,7 @@ main (int argc, char *argv[])
setlocale (LC_ALL, "");
- /* Set the default for exec_shield. */
- if (! access ("/proc/sys/kernel/exec-shield", F_OK))
- exec_shield = 1;
+ exec_shield = 2;
prelink_init_cache ();
@@ -247,6 +277,11 @@ main (int argc, char *argv[])
argp_parse (&argp, argc, argv, 0, &remaining, 0);
+ if(!noreexecinit) {
+ initctime = get_ctime("/sbin/init");
+ atexit(checkinit);
+ }
+
if (ld_library_path == NULL)
ld_library_path = getenv ("LD_LIBRARY_PATH");
@@ -261,6 +296,41 @@ main (int argc, char *argv[])
if ((undo || verify) && quick)
error (EXIT_FAILURE, 0, "--undo and --quick options are incompatible");
+ /* Set the default for exec_shield. */
+ if (exec_shield == 2)
+ {
+ if (sysroot == NULL && ! access ("/proc/sys/kernel/exec-shield", F_OK))
+ exec_shield = 1;
+ else
+ exec_shield = 0;
+ }
+
+#ifdef DEFAULT_SYSROOT
+ if (sysroot == NULL)
+ {
+ extern char *make_relative_prefix (const char *, const char *, const char *);
+ sysroot = make_relative_prefix (argv[0], BINDIR, DEFAULT_SYSROOT);
+ }
+#endif
+
+ if (sysroot)
+ {
+ sysroot = canonicalize_file_name (sysroot);
+ if (sysroot == NULL)
+ error (EXIT_FAILURE, 0, "Could not canonicalize --root argument");
+ asprintf ((char **) &prelink_conf, "%s%s", sysroot, prelink_conf);
+ }
+ if (prelink_rtld != NULL && prelink_rtld[0] == 0)
+ prelink_rtld = NULL;
+ else
+ if (prelink_rtld == NULL)
+ {
+ extern char *make_relative_prefix (const char *, const char *, const char *);
+ const char *path = make_relative_prefix (argv[0], BINDIR, BINDIR);
+ asprintf ((char **) &prelink_rtld, "%s/%s", path,
+ PRELINK_RTLD_PROG EXEEXT);
+ }
+
if (print_cache)
{
prelink_load_cache ();