diff options
author | Rob Landley <rob@landley.net> | 2018-07-02 23:56:34 -0500 |
---|---|---|
committer | Rob Landley <rob@landley.net> | 2018-07-02 23:56:34 -0500 |
commit | 7771e94e2a082726142387476937d7f136f65147 (patch) | |
tree | 64b170b0f703cfab1332e8dae1b3b4faf58ca458 | |
parent | 92a54f8092c3e7c5dafacea77f529d88ec5912b2 (diff) | |
download | toybox-7771e94e2a082726142387476937d7f136f65147.tar.gz |
Dereference one layer of symlink in multiplexer on lookup failure, so you can
"ln -s gsed sed" or similar if you need to use nonstandard names for things.
-rw-r--r-- | main.c | 26 |
1 files changed, 17 insertions, 9 deletions
@@ -34,7 +34,7 @@ struct toy_list *toy_find(char *name) { int top, bottom, middle; - if (!CFG_TOYBOX) return 0; + if (!CFG_TOYBOX || strchr(name, '/')) return 0; // If the name starts with "toybox" accept that as a match. Otherwise // skip the first entry, which is out of order. @@ -145,14 +145,12 @@ void toy_init(struct toy_list *which, char *argv[]) toy_singleinit(which, argv); } -// Like exec() but runs an internal toybox command instead of another file. -// Only returns if it can't run command internally, otherwise exit() when done. -void toy_exec(char *argv[]) +// Run an internal toybox command. +// Only returns if it can't run command internally, otherwise xexit() when done. +void toy_exec_which(struct toy_list *which, char *argv[]) { - struct toy_list *which; - // Return if we can't find it (which includes no multiplexer case), - if (!(which = toy_find(*argv))) return; + if (!which) return; // Return if stack depth getting noticeable (proxy for leaked heap, etc). @@ -170,6 +168,12 @@ void toy_exec(char *argv[]) xexit(); } +// Lookup internal toybox command to run via argv[0] +void toy_exec(char *argv[]) +{ + toy_exec_which(toy_find(basename(*argv)), argv); +} + // Multiplexer command, first argument is command to run, rest are args to that. // If first argument starts with - output list of command install paths. void toybox_main(void) @@ -179,7 +183,12 @@ void toybox_main(void) // fast path: try to exec immediately. // (Leave toys.which null to disable suid return logic.) - if (toys.argv[1]) toy_exec(toys.argv+1); + // Try dereferencing one layer of symlink + if (toys.argv[1]) { + toy_exec(toys.argv+1); + if (0<readlink(toys.argv[1], libbuf, sizeof(libbuf))) + toy_exec_which(toy_find(basename(libbuf)), toys.argv); + } // For early error reporting toys.which = toy_list; @@ -214,7 +223,6 @@ int main(int argc, char *argv[]) toys.stacktop = &stack; } - *argv = getbasename(*argv); // Up to and including Android M, bionic's dynamic linker added a handler to // cause a crash dump on SIGPIPE. That was removed in Android N, but adbd |