| 446 | } |
| 447 | |
| 448 | static int execCommand(poptContext con) |
| 449 | { |
| 450 | poptItem item = con->doExec; |
| 451 | poptArgv argv = NULL; |
| 452 | int argc = 0; |
| 453 | int rc; |
| 454 | int ec = POPT_ERROR_ERRNO; |
| 455 | |
| 456 | if (item == NULL) /*XXX can't happen*/ |
| 457 | return POPT_ERROR_NOARG; |
| 458 | |
| 459 | if (item->argv == NULL || item->argc < 1 || |
| 460 | (!con->execAbsolute && strchr(item->argv[0], '/'))) |
| 461 | return POPT_ERROR_NOARG; |
| 462 | |
| 463 | argv = malloc(sizeof(*argv) * |
| 464 | (6 + item->argc + con->numLeftovers + con->finalArgvCount)); |
| 465 | if (argv == NULL) return POPT_ERROR_MALLOC; |
| 466 | |
| 467 | if (!strchr(item->argv[0], '/') && con->execPath != NULL) { |
| 468 | char *s = malloc(strlen(con->execPath) + strlen(item->argv[0]) + sizeof("/")); |
| 469 | if (s) |
| 470 | (void)stpcpy(stpcpy(stpcpy(s, con->execPath), "/"), item->argv[0]); |
| 471 | |
| 472 | argv[argc] = s; |
| 473 | } else |
| 474 | argv[argc] = findProgramPath(item->argv[0]); |
| 475 | if (argv[argc++] == NULL) { |
| 476 | ec = POPT_ERROR_NOARG; |
| 477 | goto exit; |
| 478 | } |
| 479 | |
| 480 | if (item->argc > 1) { |
| 481 | memcpy(argv + argc, item->argv + 1, sizeof(*argv) * (item->argc - 1)); |
| 482 | argc += (item->argc - 1); |
| 483 | } |
| 484 | |
| 485 | if (con->finalArgv != NULL && con->finalArgvCount > 0) { |
| 486 | memcpy(argv + argc, con->finalArgv, |
| 487 | sizeof(*argv) * con->finalArgvCount); |
| 488 | argc += con->finalArgvCount; |
| 489 | } |
| 490 | |
| 491 | if (con->leftovers != NULL && con->numLeftovers > 0) { |
| 492 | memcpy(argv + argc, con->leftovers, sizeof(*argv) * con->numLeftovers); |
| 493 | argc += con->numLeftovers; |
| 494 | } |
| 495 | |
| 496 | argv[argc] = NULL; |
| 497 | |
| 498 | #if defined(hpux) || defined(__hpux) |
| 499 | rc = setresgid(getgid(), getgid(),-1); |
| 500 | if (rc) goto exit; |
| 501 | rc = setresuid(getuid(), getuid(),-1); |
| 502 | if (rc) goto exit; |
| 503 | #else |
| 504 | /* |
| 505 | * XXX " ... on BSD systems setuid() should be preferred over setreuid()" |
no test coverage detected