|
12 | 12 | #include "repository.h"
|
13 | 13 | #include "run-command.h"
|
14 | 14 | #include "strbuf.h"
|
| 15 | +#include "string-list.h" |
15 | 16 | #include "symlinks.h"
|
16 | 17 | #include "trace2.h"
|
17 | 18 | #include "win32.h"
|
@@ -1761,6 +1762,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
|
1761 | 1762 | return NULL;
|
1762 | 1763 | }
|
1763 | 1764 |
|
| 1765 | +static char *path_lookup(const char *cmd, int exe_only); |
| 1766 | + |
| 1767 | +static char *is_busybox_applet(const char *cmd) |
| 1768 | +{ |
| 1769 | + static struct string_list applets = STRING_LIST_INIT_DUP; |
| 1770 | + static char *busybox_path; |
| 1771 | + static int busybox_path_initialized; |
| 1772 | + |
| 1773 | + /* Avoid infinite loop */ |
| 1774 | + if (!strncasecmp(cmd, "busybox", 7) && |
| 1775 | + (!cmd[7] || !strcasecmp(cmd + 7, ".exe"))) |
| 1776 | + return NULL; |
| 1777 | + |
| 1778 | + if (!busybox_path_initialized) { |
| 1779 | + busybox_path = path_lookup("busybox.exe", 1); |
| 1780 | + busybox_path_initialized = 1; |
| 1781 | + } |
| 1782 | + |
| 1783 | + /* Assume that sh is compiled in... */ |
| 1784 | + if (!busybox_path || !strcasecmp(cmd, "sh")) |
| 1785 | + return xstrdup_or_null(busybox_path); |
| 1786 | + |
| 1787 | + if (!applets.nr) { |
| 1788 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1789 | + struct strbuf buf = STRBUF_INIT; |
| 1790 | + char *p; |
| 1791 | + |
| 1792 | + strvec_pushl(&cp.args, busybox_path, "--help", NULL); |
| 1793 | + |
| 1794 | + if (capture_command(&cp, &buf, 2048)) { |
| 1795 | + string_list_append(&applets, ""); |
| 1796 | + return NULL; |
| 1797 | + } |
| 1798 | + |
| 1799 | + /* parse output */ |
| 1800 | + p = strstr(buf.buf, "Currently defined functions:\n"); |
| 1801 | + if (!p) { |
| 1802 | + warning("Could not parse output of busybox --help"); |
| 1803 | + string_list_append(&applets, ""); |
| 1804 | + return NULL; |
| 1805 | + } |
| 1806 | + p = strchrnul(p, '\n'); |
| 1807 | + for (;;) { |
| 1808 | + size_t len; |
| 1809 | + |
| 1810 | + p += strspn(p, "\n\t ,"); |
| 1811 | + len = strcspn(p, "\n\t ,"); |
| 1812 | + if (!len) |
| 1813 | + break; |
| 1814 | + p[len] = '\0'; |
| 1815 | + string_list_insert(&applets, p); |
| 1816 | + p = p + len + 1; |
| 1817 | + } |
| 1818 | + } |
| 1819 | + |
| 1820 | + return string_list_has_string(&applets, cmd) ? |
| 1821 | + xstrdup(busybox_path) : NULL; |
| 1822 | +} |
| 1823 | + |
1764 | 1824 | /*
|
1765 | 1825 | * Determines the absolute path of cmd using the split path in path.
|
1766 | 1826 | * If cmd contains a slash or backslash, no lookup is performed.
|
@@ -1789,6 +1849,9 @@ static char *path_lookup(const char *cmd, int exe_only)
|
1789 | 1849 | path = sep + 1;
|
1790 | 1850 | }
|
1791 | 1851 |
|
| 1852 | + if (!prog && !isexe) |
| 1853 | + prog = is_busybox_applet(cmd); |
| 1854 | + |
1792 | 1855 | return prog;
|
1793 | 1856 | }
|
1794 | 1857 |
|
|
0 commit comments