|
13 | 13 | #include "dir.h"
|
14 | 14 | #include "win32/fscache.h"
|
15 | 15 | #include "../attr.h"
|
| 16 | +#include "../string-list.h" |
16 | 17 |
|
17 | 18 | #define HCAST(type, handle) ((type)(intptr_t)handle)
|
18 | 19 |
|
@@ -1411,6 +1412,65 @@ static char *lookup_prog(const char *dir, int dirlen, const char *cmd,
|
1411 | 1412 | return NULL;
|
1412 | 1413 | }
|
1413 | 1414 |
|
| 1415 | +static char *path_lookup(const char *cmd, int exe_only); |
| 1416 | + |
| 1417 | +static char *is_busybox_applet(const char *cmd) |
| 1418 | +{ |
| 1419 | + static struct string_list applets = STRING_LIST_INIT_DUP; |
| 1420 | + static char *busybox_path; |
| 1421 | + static int busybox_path_initialized; |
| 1422 | + |
| 1423 | + /* Avoid infinite loop */ |
| 1424 | + if (!strncasecmp(cmd, "busybox", 7) && |
| 1425 | + (!cmd[7] || !strcasecmp(cmd + 7, ".exe"))) |
| 1426 | + return NULL; |
| 1427 | + |
| 1428 | + if (!busybox_path_initialized) { |
| 1429 | + busybox_path = path_lookup("busybox.exe", 1); |
| 1430 | + busybox_path_initialized = 1; |
| 1431 | + } |
| 1432 | + |
| 1433 | + /* Assume that sh is compiled in... */ |
| 1434 | + if (!busybox_path || !strcasecmp(cmd, "sh")) |
| 1435 | + return xstrdup_or_null(busybox_path); |
| 1436 | + |
| 1437 | + if (!applets.nr) { |
| 1438 | + struct child_process cp = CHILD_PROCESS_INIT; |
| 1439 | + struct strbuf buf = STRBUF_INIT; |
| 1440 | + char *p; |
| 1441 | + |
| 1442 | + argv_array_pushl(&cp.args, busybox_path, "--help", NULL); |
| 1443 | + |
| 1444 | + if (capture_command(&cp, &buf, 2048)) { |
| 1445 | + string_list_append(&applets, ""); |
| 1446 | + return NULL; |
| 1447 | + } |
| 1448 | + |
| 1449 | + /* parse output */ |
| 1450 | + p = strstr(buf.buf, "Currently defined functions:\n"); |
| 1451 | + if (!p) { |
| 1452 | + warning("Could not parse output of busybox --help"); |
| 1453 | + string_list_append(&applets, ""); |
| 1454 | + return NULL; |
| 1455 | + } |
| 1456 | + p = strchrnul(p, '\n'); |
| 1457 | + for (;;) { |
| 1458 | + size_t len; |
| 1459 | + |
| 1460 | + p += strspn(p, "\n\t ,"); |
| 1461 | + len = strcspn(p, "\n\t ,"); |
| 1462 | + if (!len) |
| 1463 | + break; |
| 1464 | + p[len] = '\0'; |
| 1465 | + string_list_insert(&applets, p); |
| 1466 | + p = p + len + 1; |
| 1467 | + } |
| 1468 | + } |
| 1469 | + |
| 1470 | + return string_list_has_string(&applets, cmd) ? |
| 1471 | + xstrdup(busybox_path) : NULL; |
| 1472 | +} |
| 1473 | + |
1414 | 1474 | /*
|
1415 | 1475 | * Determines the absolute path of cmd using the split path in path.
|
1416 | 1476 | * If cmd contains a slash or backslash, no lookup is performed.
|
@@ -1439,6 +1499,9 @@ static char *path_lookup(const char *cmd, int exe_only)
|
1439 | 1499 | path = sep + 1;
|
1440 | 1500 | }
|
1441 | 1501 |
|
| 1502 | + if (!prog && !isexe) |
| 1503 | + prog = is_busybox_applet(cmd); |
| 1504 | + |
1442 | 1505 | return prog;
|
1443 | 1506 | }
|
1444 | 1507 |
|
|
0 commit comments