|
11 | 11 | #include "dir.h"
|
12 | 12 | #include "win32/fscache.h"
|
13 | 13 | #include "../attr.h"
|
| 14 | +#include "../string-list.h" |
14 | 15 |
|
15 | 16 | #define HCAST(type, handle) ((type)(intptr_t)handle)
|
16 | 17 |
|
@@ -1536,6 +1537,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
|
1536 | 1537 | return NULL;
|
1537 | 1538 | }
|
1538 | 1539 |
|
| 1540 | +static char *path_lookup(const char *cmd, int exe_only); |
| 1541 | + |
| 1542 | +static char *is_busybox_applet(const char *cmd) |
| 1543 | +{ |
| 1544 | + static struct string_list applets = STRING_LIST_INIT_DUP; |
| 1545 | + static char *busybox_path; |
| 1546 | + static int busybox_path_initialized; |
| 1547 | + |
| 1548 | + /* Avoid infinite loop */ |
| 1549 | + if (!strncasecmp(cmd, "busybox", 7) && |
| 1550 | + (!cmd[7] || !strcasecmp(cmd + 7, ".exe"))) |
| 1551 | + return NULL; |
| 1552 | + |
| 1553 | + if (!busybox_path_initialized) { |
| 1554 | + busybox_path = path_lookup("busybox.exe", 1); |
| 1555 | + busybox_path_initialized = 1; |
| 1556 | + } |
| 1557 | + |
| 1558 | + /* Assume that sh is compiled in... */ |
| 1559 | + if (!busybox_path || !strcasecmp(cmd, "sh")) |
| 1560 | + return xstrdup_or_null(busybox_path); |
| 1561 | + |
| 1562 | + if (!applets.nr) { |
| 1563 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1564 | + struct strbuf buf = STRBUF_INIT; |
| 1565 | + char *p; |
| 1566 | + |
| 1567 | + strvec_pushl(&cp.args, busybox_path, "--help", NULL); |
| 1568 | + |
| 1569 | + if (capture_command(&cp, &buf, 2048)) { |
| 1570 | + string_list_append(&applets, ""); |
| 1571 | + return NULL; |
| 1572 | + } |
| 1573 | + |
| 1574 | + /* parse output */ |
| 1575 | + p = strstr(buf.buf, "Currently defined functions:\n"); |
| 1576 | + if (!p) { |
| 1577 | + warning("Could not parse output of busybox --help"); |
| 1578 | + string_list_append(&applets, ""); |
| 1579 | + return NULL; |
| 1580 | + } |
| 1581 | + p = strchrnul(p, '\n'); |
| 1582 | + for (;;) { |
| 1583 | + size_t len; |
| 1584 | + |
| 1585 | + p += strspn(p, "\n\t ,"); |
| 1586 | + len = strcspn(p, "\n\t ,"); |
| 1587 | + if (!len) |
| 1588 | + break; |
| 1589 | + p[len] = '\0'; |
| 1590 | + string_list_insert(&applets, p); |
| 1591 | + p = p + len + 1; |
| 1592 | + } |
| 1593 | + } |
| 1594 | + |
| 1595 | + return string_list_has_string(&applets, cmd) ? |
| 1596 | + xstrdup(busybox_path) : NULL; |
| 1597 | +} |
| 1598 | + |
1539 | 1599 | /*
|
1540 | 1600 | * Determines the absolute path of cmd using the split path in path.
|
1541 | 1601 | * If cmd contains a slash or backslash, no lookup is performed.
|
@@ -1564,6 +1624,9 @@ static char *path_lookup(const char *cmd, int exe_only)
|
1564 | 1624 | path = sep + 1;
|
1565 | 1625 | }
|
1566 | 1626 |
|
| 1627 | + if (!prog && !isexe) |
| 1628 | + prog = is_busybox_applet(cmd); |
| 1629 | + |
1567 | 1630 | return prog;
|
1568 | 1631 | }
|
1569 | 1632 |
|
|
0 commit comments