// bootshell.cc
//
// v. 1.3
//
// A very (very!) limited shell intended to run as the boot prompt
// for a Linux390 system.  The goal here is to allow the VMOPER to
// halt the Linux390 system without knowing the root password, while
// still preserving system security.  The assumptions are made that:
// a) Your opers are trusted to halt the system
// b) Your VM account password is not your root password.
//
// When executed, prompts for either a HALT command or a LOGIN
// HALT will execute a system halt (however defined via HALT_CMD
// LOGIN will execute a password login prompt (however defined via LOGIN_CMD)
//
// Use CP SET SECUSER <ACCOUNT> before linux IPL (or after Linux IPL via
// HCP) to authorize an account that may use CP SEND to issue the halt command
//
// Edit /etc/inittab and replace
// 1:2345:respawn:/sbin/sulogin /dev/console
// with
// 1:2345:respawn:/sbin/bootshell
//
// Mike Kershaw (urmk@reason.marist.edu)
//
// v1.1 (07-21-2000) - Added patches by John Dalbec to fix loop
//                     on ^D and typo
//
// v1.3 (12-07-2000) - Added more patches from John to fix some very bad 
//                     behavior.  NULL-terminated is important!  Doh! 

#include <iostream.h>
#include <string>
#include <unistd.h>

// These commands must be formatted as argv[] arrays
// Command to execute for login
char *login_cmd[] = {"/sbin/sulogin", NULL};
// Command to execute for halt
char *halt_cmd[] = {"/sbin/shutdown", "-h", "now", "REMOTE SHUTDOWN REQUESTED", NULL};

// small function to lowercase a c++ string
string StrLower(string in_str) {
    string thestr = in_str;
    for (int i = 0; i < thestr.length(); i++)
        thestr[i] = tolower(thestr[i]);

    return thestr;
}

int main(int argc, char *argv[]) {
    string input;

    for (;;) {
        cout << "Enter 'halt' to shutdown the system" << endl;
        cout << "or 'login' for maintenance login." << endl;
        cout << "Linux390: ";
        cin >> input;

        input = StrLower(input);
        if (input == "login") {
            // exec login
            cout << "*** Executing login command." << endl;
            if (execvp(login_cmd[0], &login_cmd[0]) < 0)
                cout << "*** Could not execute login command." << endl;
        } else if (input == "halt") {
            // exec halt
            cout << "*** Executing halt command." << endl;
            if (execvp(halt_cmd[0], &halt_cmd[0]) < 0)
                cout << "*** Could not execute halt command." << endl;
        } else if (cin.eof()) {
            // exit to avoid infinite loop
           cout << endl;
           break;
        }

    }

    exit (0);

}