|
14 | 14 | #include <sspi.h> |
15 | 15 | #include "win32/fscache.h" |
16 | 16 | #include "../attr.h" |
| 17 | +#include "../string-list.h" |
17 | 18 |
|
18 | 19 | #define HCAST(type, handle) ((type)(intptr_t)handle) |
19 | 20 |
|
@@ -1585,6 +1586,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd, |
1585 | 1586 | return NULL; |
1586 | 1587 | } |
1587 | 1588 |
|
| 1589 | +static char *path_lookup(const char *cmd, int exe_only); |
| 1590 | + |
| 1591 | +static char *is_busybox_applet(const char *cmd) |
| 1592 | +{ |
| 1593 | + static struct string_list applets = STRING_LIST_INIT_DUP; |
| 1594 | + static char *busybox_path; |
| 1595 | + static int busybox_path_initialized; |
| 1596 | + |
| 1597 | + /* Avoid infinite loop */ |
| 1598 | + if (!strncasecmp(cmd, "busybox", 7) && |
| 1599 | + (!cmd[7] || !strcasecmp(cmd + 7, ".exe"))) |
| 1600 | + return NULL; |
| 1601 | + |
| 1602 | + if (!busybox_path_initialized) { |
| 1603 | + busybox_path = path_lookup("busybox.exe", 1); |
| 1604 | + busybox_path_initialized = 1; |
| 1605 | + } |
| 1606 | + |
| 1607 | + /* Assume that sh is compiled in... */ |
| 1608 | + if (!busybox_path || !strcasecmp(cmd, "sh")) |
| 1609 | + return xstrdup_or_null(busybox_path); |
| 1610 | + |
| 1611 | + if (!applets.nr) { |
| 1612 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1613 | + struct strbuf buf = STRBUF_INIT; |
| 1614 | + char *p; |
| 1615 | + |
| 1616 | + strvec_pushl(&cp.args, busybox_path, "--help", NULL); |
| 1617 | + |
| 1618 | + if (capture_command(&cp, &buf, 2048)) { |
| 1619 | + string_list_append(&applets, ""); |
| 1620 | + return NULL; |
| 1621 | + } |
| 1622 | + |
| 1623 | + /* parse output */ |
| 1624 | + p = strstr(buf.buf, "Currently defined functions:\n"); |
| 1625 | + if (!p) { |
| 1626 | + warning("Could not parse output of busybox --help"); |
| 1627 | + string_list_append(&applets, ""); |
| 1628 | + return NULL; |
| 1629 | + } |
| 1630 | + p = strchrnul(p, '\n'); |
| 1631 | + for (;;) { |
| 1632 | + size_t len; |
| 1633 | + |
| 1634 | + p += strspn(p, "\n\t ,"); |
| 1635 | + len = strcspn(p, "\n\t ,"); |
| 1636 | + if (!len) |
| 1637 | + break; |
| 1638 | + p[len] = '\0'; |
| 1639 | + string_list_insert(&applets, p); |
| 1640 | + p = p + len + 1; |
| 1641 | + } |
| 1642 | + } |
| 1643 | + |
| 1644 | + return string_list_has_string(&applets, cmd) ? |
| 1645 | + xstrdup(busybox_path) : NULL; |
| 1646 | +} |
| 1647 | + |
1588 | 1648 | /* |
1589 | 1649 | * Determines the absolute path of cmd using the split path in path. |
1590 | 1650 | * If cmd contains a slash or backslash, no lookup is performed. |
@@ -1613,6 +1673,9 @@ static char *path_lookup(const char *cmd, int exe_only) |
1613 | 1673 | path = sep + 1; |
1614 | 1674 | } |
1615 | 1675 |
|
| 1676 | + if (!prog && !isexe) |
| 1677 | + prog = is_busybox_applet(cmd); |
| 1678 | + |
1616 | 1679 | return prog; |
1617 | 1680 | } |
1618 | 1681 |
|
|
0 commit comments