|
23 | 23 | #include "../repository.h"
|
24 | 24 | #include "win32/fscache.h"
|
25 | 25 | #include "../attr.h"
|
| 26 | +#include "../string-list.h" |
26 | 27 |
|
27 | 28 | #define HCAST(type, handle) ((type)(intptr_t)handle)
|
28 | 29 |
|
@@ -1651,6 +1652,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
|
1651 | 1652 | return NULL;
|
1652 | 1653 | }
|
1653 | 1654 |
|
| 1655 | +static char *path_lookup(const char *cmd, int exe_only); |
| 1656 | + |
| 1657 | +static char *is_busybox_applet(const char *cmd) |
| 1658 | +{ |
| 1659 | + static struct string_list applets = STRING_LIST_INIT_DUP; |
| 1660 | + static char *busybox_path; |
| 1661 | + static int busybox_path_initialized; |
| 1662 | + |
| 1663 | + /* Avoid infinite loop */ |
| 1664 | + if (!strncasecmp(cmd, "busybox", 7) && |
| 1665 | + (!cmd[7] || !strcasecmp(cmd + 7, ".exe"))) |
| 1666 | + return NULL; |
| 1667 | + |
| 1668 | + if (!busybox_path_initialized) { |
| 1669 | + busybox_path = path_lookup("busybox.exe", 1); |
| 1670 | + busybox_path_initialized = 1; |
| 1671 | + } |
| 1672 | + |
| 1673 | + /* Assume that sh is compiled in... */ |
| 1674 | + if (!busybox_path || !strcasecmp(cmd, "sh")) |
| 1675 | + return xstrdup_or_null(busybox_path); |
| 1676 | + |
| 1677 | + if (!applets.nr) { |
| 1678 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1679 | + struct strbuf buf = STRBUF_INIT; |
| 1680 | + char *p; |
| 1681 | + |
| 1682 | + strvec_pushl(&cp.args, busybox_path, "--help", NULL); |
| 1683 | + |
| 1684 | + if (capture_command(&cp, &buf, 2048)) { |
| 1685 | + string_list_append(&applets, ""); |
| 1686 | + return NULL; |
| 1687 | + } |
| 1688 | + |
| 1689 | + /* parse output */ |
| 1690 | + p = strstr(buf.buf, "Currently defined functions:\n"); |
| 1691 | + if (!p) { |
| 1692 | + warning("Could not parse output of busybox --help"); |
| 1693 | + string_list_append(&applets, ""); |
| 1694 | + return NULL; |
| 1695 | + } |
| 1696 | + p = strchrnul(p, '\n'); |
| 1697 | + for (;;) { |
| 1698 | + size_t len; |
| 1699 | + |
| 1700 | + p += strspn(p, "\n\t ,"); |
| 1701 | + len = strcspn(p, "\n\t ,"); |
| 1702 | + if (!len) |
| 1703 | + break; |
| 1704 | + p[len] = '\0'; |
| 1705 | + string_list_insert(&applets, p); |
| 1706 | + p = p + len + 1; |
| 1707 | + } |
| 1708 | + } |
| 1709 | + |
| 1710 | + return string_list_has_string(&applets, cmd) ? |
| 1711 | + xstrdup(busybox_path) : NULL; |
| 1712 | +} |
| 1713 | + |
1654 | 1714 | /*
|
1655 | 1715 | * Determines the absolute path of cmd using the split path in path.
|
1656 | 1716 | * If cmd contains a slash or backslash, no lookup is performed.
|
@@ -1679,6 +1739,9 @@ static char *path_lookup(const char *cmd, int exe_only)
|
1679 | 1739 | path = sep + 1;
|
1680 | 1740 | }
|
1681 | 1741 |
|
| 1742 | + if (!prog && !isexe) |
| 1743 | + prog = is_busybox_applet(cmd); |
| 1744 | + |
1682 | 1745 | return prog;
|
1683 | 1746 | }
|
1684 | 1747 |
|
|
0 commit comments