- int fd;
- int tried_devcons = 0;
- int tried_vtprimary = 0;
- struct vt_stat vt;
- struct serial_struct sr;
- char *s;
-
- if ((s = getenv("TERM")) != NULL) {
- snprintf(termType, sizeof(termType) - 1, "TERM=%s", s);
- }
-
- if ((s = getenv("CONSOLE")) != NULL) {
- safe_strncpy(console, s, sizeof(console));
- }
-#if #cpu(sparc)
- /* sparc kernel supports console=tty[ab] parameter which is also
- * passed to init, so catch it here */
- else if ((s = getenv("console")) != NULL) {
- /* remap tty[ab] to /dev/ttyS[01] */
- if (strcmp(s, "ttya") == 0)
- safe_strncpy(console, SC_0, sizeof(console));
- else if (strcmp(s, "ttyb") == 0)
- safe_strncpy(console, SC_1, sizeof(console));
- }
-#endif
- else {
- /* 2.2 kernels: identify the real console backend and try to use it */
- if (ioctl(0, TIOCGSERIAL, &sr) == 0) {
- /* this is a serial console */
- snprintf(console, sizeof(console) - 1, SC_FORMAT, sr.line);
- } else if (ioctl(0, VT_GETSTATE, &vt) == 0) {
- /* this is linux virtual tty */
- snprintf(console, sizeof(console) - 1, VC_FORMAT, vt.v_active);
- } else {
- safe_strncpy(console, _PATH_CONSOLE, sizeof(console));
- tried_devcons++;
- }
- }
-
- while ((fd = open(console, O_RDONLY | O_NONBLOCK)) < 0) {
- /* Can't open selected console -- try /dev/console */
- if (!tried_devcons) {
- tried_devcons++;
- safe_strncpy(console, _PATH_CONSOLE, sizeof(console));
- continue;
- }
- /* Can't open selected console -- try vt1 */
- if (!tried_vtprimary) {
- tried_vtprimary++;
- safe_strncpy(console, VC_1, sizeof(console));
- continue;
- }
- break;
- }
- if (fd < 0) {
- /* Perhaps we should panic here? */
- safe_strncpy(console, "/dev/null", sizeof(console));
+ char *cmd[COMMAND_SIZE / 2];
+ char buf[COMMAND_SIZE + 6]; /* COMMAND_SIZE+strlen("exec ")+1 */
+ int dash = (command[0] == '-' /* maybe? && command[1] == '/' */);
+
+ /* See if any special /bin/sh requiring characters are present */
+ if (strpbrk(command, "~`!$^&*()=|\\{}[];\"'<>?") != NULL) {
+ strcpy(buf, "exec ");
+ strcpy(buf + 5, command + dash); /* excluding "-" */
+ /* NB: LIBBB_DEFAULT_LOGIN_SHELL define has leading dash */
+ cmd[0] = (char*)(LIBBB_DEFAULT_LOGIN_SHELL + !dash);
+ cmd[1] = (char*)"-c";
+ cmd[2] = buf;
+ cmd[3] = NULL;