131457Sminshall #include <sys/types.h> 231457Sminshall #include <sys/socket.h> 331457Sminshall #include <netinet/in.h> 431455Sminshall #include <sys/wait.h> 531455Sminshall 631457Sminshall #include <errno.h> 731457Sminshall extern int errno; 831457Sminshall 931457Sminshall #include <netdb.h> 1031457Sminshall #include <signal.h> 1131455Sminshall #include <stdio.h> 1231457Sminshall #include <pwd.h> 1331455Sminshall 1431455Sminshall #include "../general/general.h" 1531455Sminshall #include "../api/api.h" 1631463Sminshall #include "../apilib/api_exch.h" 1731455Sminshall 1831455Sminshall #include "../general/globals.h" 1931455Sminshall 2031455Sminshall 2131455Sminshall static int shell_pid = 0; 2231455Sminshall 2331457Sminshall static char *ourENVlist[200]; /* Lots of room */ 2431457Sminshall 2531465Sminshall static int 2631465Sminshall sock = -1, /* Connected socket */ 2731465Sminshall serversock; /* Server (listening) socket */ 2831457Sminshall 2931457Sminshall static enum { DEAD, UNCONNECTED, CONNECTED } state; 3031457Sminshall 3131455Sminshall static int 3231463Sminshall storage_location, /* Address we have */ 3331457Sminshall storage_length = 0, /* Length we have */ 3431457Sminshall storage_must_send = 0, /* Storage belongs on other side of wire */ 3531457Sminshall storage_accessed = 0; /* The storage is accessed (so leave alone)! */ 3631457Sminshall 3731503Sminshall static long storage[1000]; 3831457Sminshall 3931463Sminshall static union REGS inputRegs; 4031463Sminshall static struct SREGS inputSregs; 4131457Sminshall 4231463Sminshall 4331463Sminshall static void 4431457Sminshall kill_connection() 4531457Sminshall { 4631465Sminshall state = UNCONNECTED; 4731465Sminshall if (sock != -1) { 4831465Sminshall (void) close(sock); 4931465Sminshall sock = -1; 5031465Sminshall } 5131457Sminshall } 5231457Sminshall 5331457Sminshall 5431457Sminshall static int 5531463Sminshall nextstore() 5631455Sminshall { 5731463Sminshall struct storage_descriptor sd; 5831455Sminshall 5931463Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 6031457Sminshall storage_length = 0; 6131457Sminshall return -1; 6231457Sminshall } 6331463Sminshall storage_length = ntohs(sd.length); 6431463Sminshall storage_location = ntohl(sd.location); 6531463Sminshall if (storage_length > sizeof storage) { 6631457Sminshall fprintf(stderr, "API client tried to send too much storage (%d).\n", 6731457Sminshall storage_length); 6831463Sminshall storage_length = 0; 6931457Sminshall return -1; 7031457Sminshall } 7131471Sminshall if (storage_length != 0) { 7231471Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage) 7331471Sminshall == -1) { 7431471Sminshall storage_length = 0; 7531471Sminshall return -1; 7631471Sminshall } 7731463Sminshall } 7831471Sminshall return 0; 7931457Sminshall } 8031457Sminshall 8131457Sminshall 8231457Sminshall static int 8331457Sminshall doreject(message) 8431457Sminshall char *message; 8531457Sminshall { 8631463Sminshall struct storage_descriptor sd; 8731457Sminshall int length = strlen(message); 8831457Sminshall 8931492Sminshall if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) { 9031457Sminshall return -1; 9131457Sminshall } 9231463Sminshall sd.length = htons(length); 9331465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 9431463Sminshall return -1; 9531463Sminshall } 9631463Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, message) == -1) { 9731463Sminshall return -1; 9831463Sminshall } 9931457Sminshall return 0; 10031457Sminshall } 10131457Sminshall 10231457Sminshall 10331455Sminshall /* 10431465Sminshall * doassociate() 10531457Sminshall * 10631457Sminshall * Negotiate with the other side and try to do something. 10731457Sminshall */ 10831457Sminshall 10931457Sminshall static int 11031465Sminshall doassociate() 11131457Sminshall { 11231457Sminshall struct passwd *pwent; 11331457Sminshall char 11431457Sminshall promptbuf[100], 11531457Sminshall buffer[200]; 11631457Sminshall int length; 11731457Sminshall int was; 11831463Sminshall struct storage_descriptor sd; 11931457Sminshall 12031457Sminshall if ((pwent = getpwuid(geteuid())) == 0) { 12131457Sminshall return -1; 12231457Sminshall } 12331457Sminshall sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name); 12431492Sminshall if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) { 12531465Sminshall return -1; 12631465Sminshall } 12731465Sminshall sd.length = htons(strlen(promptbuf)); 12831465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 12931465Sminshall return -1; 13031465Sminshall } 13131465Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf) == -1) { 13231465Sminshall return -1; 13331465Sminshall } 13431465Sminshall sd.length = htons(strlen(pwent->pw_name)); 13531465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 13631465Sminshall return -1; 13731465Sminshall } 13831465Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, 13931465Sminshall strlen(pwent->pw_name), pwent->pw_name) == -1) { 14031465Sminshall return -1; 14131465Sminshall } 14231492Sminshall if (api_exch_incommand(EXCH_CMD_AUTH) == -1) { 14331457Sminshall return -1; 14431457Sminshall } 14531463Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 14631463Sminshall return -1; 14731457Sminshall } 14831463Sminshall sd.length = ntohs(sd.length); 14931463Sminshall if (sd.length > sizeof buffer) { 15031457Sminshall doreject("Password entered was too long"); 15131465Sminshall return -1; 15231457Sminshall } 15331463Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 15431457Sminshall return -1; 15531457Sminshall } 15631463Sminshall buffer[sd.length] = 0; 15731457Sminshall 15831457Sminshall /* Is this the correct password? */ 15931465Sminshall if (strlen(pwent->pw_name)) { 16031465Sminshall char *ptr; 16131465Sminshall int i; 16231465Sminshall 16331465Sminshall ptr = pwent->pw_name; 16431465Sminshall i = 0; 16531465Sminshall while (i < sd.length) { 16631465Sminshall buffer[i++] ^= *ptr++; 16731465Sminshall if (*ptr == 0) { 16831465Sminshall ptr = pwent->pw_name; 16931465Sminshall } 17031465Sminshall } 17131465Sminshall } 17231457Sminshall if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) == 0) { 17331492Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) { 17431465Sminshall return -1; 17531471Sminshall } else { 17631471Sminshall return 1; 17731465Sminshall } 17831457Sminshall } else { 17931457Sminshall doreject("Invalid password"); 18031457Sminshall sleep(10); /* Don't let us do too many of these */ 18131471Sminshall return 0; 18231457Sminshall } 18331457Sminshall } 18431457Sminshall 18531457Sminshall 18631457Sminshall void 18731457Sminshall freestorage() 18831457Sminshall { 18931457Sminshall char buffer[40]; 19031463Sminshall struct storage_descriptor sd; 19131457Sminshall 19231457Sminshall if (storage_accessed) { 19331457Sminshall fprintf(stderr, "Internal error - attempt to free accessed storage.\n"); 19431503Sminshall fprintf(stderr, "(Encountered in file %s at line %d.)\n", 19531457Sminshall __FILE__, __LINE__); 19631457Sminshall quit(); 19731457Sminshall } 19831457Sminshall if (storage_must_send == 0) { 19931457Sminshall return; 20031457Sminshall } 20131457Sminshall storage_must_send = 0; 20231492Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 20331457Sminshall kill_connection(); 20431457Sminshall return; 20531457Sminshall } 20631463Sminshall sd.length = htons(storage_length); 20731463Sminshall sd.location = htonl(storage_location); 20831463Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 20931457Sminshall kill_connection(); 21031457Sminshall return; 21131457Sminshall } 21231471Sminshall if (storage_length != 0) { 21331471Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage) 21431471Sminshall == -1) { 21531471Sminshall kill_connection(); 21631471Sminshall return; 21731471Sminshall } 21831463Sminshall } 21931457Sminshall } 22031457Sminshall 22131457Sminshall 22231463Sminshall static int 223*31508Sminshall getstorage(address, length, copyin) 224*31508Sminshall int 225*31508Sminshall address, 226*31508Sminshall length, 227*31508Sminshall copyin; 22831457Sminshall { 22931463Sminshall struct storage_descriptor sd; 23031457Sminshall char buffer[40]; 23131457Sminshall 23231457Sminshall freestorage(); 23331457Sminshall if (storage_accessed) { 23431457Sminshall fprintf(stderr, 23531457Sminshall "Internal error - attempt to get while storage accessed.\n"); 23631503Sminshall fprintf(stderr, "(Encountered in file %s at line %d.)\n", 23731457Sminshall __FILE__, __LINE__); 23831457Sminshall quit(); 23931457Sminshall } 24031457Sminshall storage_must_send = 0; 24131492Sminshall if (api_exch_outcommand(EXCH_CMD_GIMME) == -1) { 24231457Sminshall kill_connection(); 24331463Sminshall return -1; 24431457Sminshall } 24531471Sminshall storage_location = address; 24631471Sminshall storage_length = length; 247*31508Sminshall if (copyin) { 248*31508Sminshall sd.location = htonl(storage_location); 249*31508Sminshall sd.length = htons(storage_length); 250*31508Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, 251*31508Sminshall sizeof sd, (char *)&sd) == -1) { 252*31508Sminshall kill_connection(); 253*31508Sminshall return -1; 254*31508Sminshall } 255*31508Sminshall if (api_exch_incommand(EXCH_CMD_HEREIS) == -1) { 256*31508Sminshall fprintf(stderr, "Bad data from other side.\n"); 257*31508Sminshall fprintf(stderr, "(Encountered at %s, %d.)\n", __FILE__, __LINE__); 258*31508Sminshall return -1; 259*31508Sminshall } 260*31508Sminshall if (nextstore() == -1) { 261*31508Sminshall kill_connection(); 262*31508Sminshall return -1; 263*31508Sminshall } 26431463Sminshall } 26531463Sminshall return 0; 26631457Sminshall } 26731457Sminshall 26831457Sminshall void 26931457Sminshall movetous(local, es, di, length) 27031457Sminshall char 27131457Sminshall *local; 27231457Sminshall int 27331457Sminshall es, 27431457Sminshall di; 27531457Sminshall int 27631457Sminshall length; 27731457Sminshall { 27831457Sminshall if (length > sizeof storage) { 27931457Sminshall fprintf(stderr, "Internal API error - movetous() length too long.\n"); 28031457Sminshall fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); 28131457Sminshall quit(); 28231457Sminshall } else if (length == 0) { 28331457Sminshall return; 28431457Sminshall } 285*31508Sminshall getstorage(di, length, 1); 28631463Sminshall memcpy(local, storage+(di-storage_location), length); 28731457Sminshall } 28831457Sminshall 28931457Sminshall void 29031457Sminshall movetothem(es, di, local, length) 29131457Sminshall int 29231457Sminshall es, 29331457Sminshall di; 29431457Sminshall char 29531457Sminshall *local; 29631457Sminshall int 29731457Sminshall length; 29831457Sminshall { 29931457Sminshall if (length > sizeof storage) { 30031457Sminshall fprintf(stderr, "Internal API error - movetothem() length too long.\n"); 30131457Sminshall fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); 30231457Sminshall quit(); 30331457Sminshall } else if (length == 0) { 30431457Sminshall return; 30531457Sminshall } 30631457Sminshall freestorage(); 30731457Sminshall memcpy((char *)storage, local, length); 30831457Sminshall storage_length = length; 30931463Sminshall storage_location = di; 31031457Sminshall storage_must_send = 1; 31131457Sminshall } 31231457Sminshall 31331457Sminshall 31431457Sminshall char * 315*31508Sminshall access_api(location, length, copyin) 31631457Sminshall int 31731457Sminshall location, 318*31508Sminshall length, 319*31508Sminshall copyin; /* Do we need to copy in initially? */ 32031457Sminshall { 32131457Sminshall if (storage_accessed) { 32231457Sminshall fprintf(stderr, "Internal error - storage accessed twice\n"); 32331503Sminshall fprintf(stderr, "(Encountered in file %s, line %d.)\n", 32431457Sminshall __FILE__, __LINE__); 32531457Sminshall quit(); 32631457Sminshall } else if (length != 0) { 32731457Sminshall freestorage(); 328*31508Sminshall getstorage(location, length, copyin); 32931503Sminshall storage_accessed = 1; 33031457Sminshall } 33131457Sminshall return (char *) storage; 33231457Sminshall } 33331457Sminshall 334*31508Sminshall unaccess_api(location, local, length, copyout) 33531457Sminshall int location; 33631457Sminshall char *local; 33731457Sminshall int length; 33831457Sminshall { 33931457Sminshall if (storage_accessed == 0) { 34031457Sminshall fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n"); 34131503Sminshall fprintf(stderr, "(Encountered in file %s, line %d.)\n", 34231457Sminshall __FILE__, __LINE__); 34331457Sminshall quit(); 34431457Sminshall } 34531457Sminshall storage_accessed = 0; 346*31508Sminshall storage_must_send = copyout; /* if needs to go back */ 34731457Sminshall } 34831457Sminshall 34931465Sminshall /* 35031465Sminshall * Accept a connection from an API client, aborting if the child dies. 35131465Sminshall */ 35231457Sminshall 35331465Sminshall static int 35431465Sminshall doconnect() 35531465Sminshall { 35631465Sminshall fd_set fdset; 35731465Sminshall int i; 35831465Sminshall 35931465Sminshall sock = -1; 36031465Sminshall FD_ZERO(&fdset); 36131465Sminshall while (shell_active && (sock == -1)) { 36231465Sminshall FD_SET(serversock, &fdset); 36331465Sminshall if ((i = select(serversock+1, &fdset, 0, 0, 0)) < 0) { 36431465Sminshall if (errno = EINTR) { 36531465Sminshall continue; 36631465Sminshall } else { 36731465Sminshall perror("in select waiting for API connection"); 36831465Sminshall return -1; 36931465Sminshall } 37031465Sminshall } else { 37131465Sminshall i = accept(serversock, 0, 0); 37231465Sminshall if (i == -1) { 37331465Sminshall perror("accepting API connection"); 37431465Sminshall return -1; 37531465Sminshall } 37631465Sminshall sock = i; 37731465Sminshall } 37831465Sminshall } 37931465Sminshall /* If the process has already exited, we may need to close */ 38031465Sminshall if ((shell_active == 0) && (sock != -1)) { 38131465Sminshall (void) close(sock); 38231465Sminshall sock = -1; 38331465Sminshall setcommandmode(); /* In case child_died sneaked in */ 38431465Sminshall } 38531465Sminshall } 38631465Sminshall 38731457Sminshall /* 38831455Sminshall * shell_continue() actually runs the command, and looks for API 38931455Sminshall * requests coming back in. 39031455Sminshall * 39131455Sminshall * We are called from the main loop in telnet.c. 39231455Sminshall */ 39331455Sminshall 39431455Sminshall int 39531455Sminshall shell_continue() 39631455Sminshall { 39731492Sminshall int i; 39831492Sminshall 39931457Sminshall switch (state) { 40031457Sminshall case DEAD: 40131457Sminshall pause(); /* Nothing to do */ 40231457Sminshall break; 40331457Sminshall case UNCONNECTED: 40431465Sminshall if (doconnect() == -1) { 40531457Sminshall kill_connection(); 40631465Sminshall return -1; 40731465Sminshall } 40831492Sminshall if (api_exch_init(sock, "server") == -1) { 40931465Sminshall return -1; 41031465Sminshall } 41131465Sminshall while (state == UNCONNECTED) { 41231492Sminshall if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) { 41331457Sminshall kill_connection(); 41431465Sminshall return -1; 41531465Sminshall } else { 41631465Sminshall switch (doassociate()) { 41731465Sminshall case -1: 41831465Sminshall kill_connection(); 41931465Sminshall return -1; 42031465Sminshall case 0: 42131465Sminshall break; 42231465Sminshall case 1: 42331465Sminshall state = CONNECTED; 42431465Sminshall } 42531457Sminshall } 42631457Sminshall } 42731457Sminshall break; 42831457Sminshall case CONNECTED: 42931492Sminshall switch (i = api_exch_nextcommand()) { 43031492Sminshall case EXCH_CMD_REQUEST: 43131492Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs, 43231492Sminshall (char *)&inputRegs) == -1) { 43331463Sminshall kill_connection(); 43431492Sminshall } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs, 43531492Sminshall (char *)&inputSregs) == -1) { 43631463Sminshall kill_connection(); 43731492Sminshall } else if (nextstore() == -1) { 43831463Sminshall kill_connection(); 43931492Sminshall } else { 44031492Sminshall handle_api(&inputRegs, &inputSregs); 44131492Sminshall freestorage(); /* Send any storage back */ 44231492Sminshall if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) { 44331492Sminshall kill_connection(); 44431492Sminshall } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs, 44531492Sminshall (char *)&inputRegs) == -1) { 44631492Sminshall kill_connection(); 44731492Sminshall } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs, 44831492Sminshall (char *)&inputSregs) == -1) { 44931492Sminshall kill_connection(); 45031492Sminshall } 45131492Sminshall /* Done, and it all worked! */ 45231463Sminshall } 45331492Sminshall break; 45431492Sminshall case EXCH_CMD_DISASSOCIATE: 45531492Sminshall kill_connection(); 45631492Sminshall break; 45731492Sminshall default: 45831503Sminshall if (i != -1) { 45931503Sminshall fprintf(stderr, 46031503Sminshall "Looking for a REQUEST or DISASSOCIATE command\n"); 46131503Sminshall fprintf(stderr, "\treceived 0x%02x.\n", i); 46231503Sminshall } 46331492Sminshall kill_connection(); 46431503Sminshall break; 46531457Sminshall } 46631457Sminshall } 46731455Sminshall return shell_active; 46831455Sminshall } 46931455Sminshall 47031455Sminshall 47131463Sminshall static int 47231463Sminshall child_died() 47331463Sminshall { 47431463Sminshall union wait *status; 47531463Sminshall register int pid; 47631463Sminshall 47731463Sminshall while ((pid = wait3(&status, WNOHANG, 0)) > 0) { 47831463Sminshall if (pid == shell_pid) { 47931463Sminshall char inputbuffer[100]; 48031463Sminshall 48131463Sminshall shell_active = 0; 48231463Sminshall if (sock != -1) { 48331463Sminshall (void) close(sock); 48431463Sminshall sock = -1; 48531463Sminshall } 48631471Sminshall printf("[Hit return to continue]"); 48731471Sminshall fflush(stdout); 48831471Sminshall (void) gets(inputbuffer); 48931465Sminshall setconnmode(); 49031465Sminshall ConnectScreen(); /* Turn screen on (if need be) */ 49131465Sminshall (void) close(serversock); 49231463Sminshall } 49331463Sminshall } 49431463Sminshall signal(SIGCHLD, child_died); 49531463Sminshall } 49631463Sminshall 49731463Sminshall 49831455Sminshall /* 49931455Sminshall * Called from telnet.c to fork a lower command.com. We 50031455Sminshall * use the spint... routines so that we can pick up 50131455Sminshall * interrupts generated by application programs. 50231455Sminshall */ 50331455Sminshall 50431455Sminshall 50531455Sminshall int 50631455Sminshall shell(argc,argv) 50731455Sminshall int argc; 50831455Sminshall char *argv[]; 50931455Sminshall { 51031465Sminshall int length; 51131457Sminshall struct sockaddr_in server; 51231457Sminshall char sockNAME[100]; 51331457Sminshall static char **whereAPI = 0; 51431457Sminshall 51531457Sminshall /* First, create the socket which will be connected to */ 51631457Sminshall serversock = socket(AF_INET, SOCK_STREAM, 0); 51731457Sminshall if (serversock < 0) { 51831457Sminshall perror("opening API socket"); 51931457Sminshall return 0; 52031457Sminshall } 52131457Sminshall server.sin_family = AF_INET; 52231457Sminshall server.sin_addr.s_addr = INADDR_ANY; 52331457Sminshall server.sin_port = 0; 52431457Sminshall if (bind(serversock, &server, sizeof server) < 0) { 52531457Sminshall perror("binding API socket"); 52631457Sminshall return 0; 52731457Sminshall } 52831457Sminshall length = sizeof server; 52931457Sminshall if (getsockname(serversock, &server, &length) < 0) { 53031457Sminshall perror("getting API socket name"); 53131457Sminshall (void) close(serversock); 53231457Sminshall } 53331457Sminshall listen(serversock, 1); 53431457Sminshall /* Get name to advertise in address list */ 53531457Sminshall strcpy(sockNAME, "API3270="); 53631457Sminshall gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME)); 53731457Sminshall if (strlen(sockNAME) > (sizeof sockNAME-10)) { 53831457Sminshall fprintf(stderr, "Local hostname too large; using 'localhost'.\n"); 53931457Sminshall strcpy(sockNAME, "localhost"); 54031457Sminshall } 54131457Sminshall sprintf(sockNAME+strlen(sockNAME), ":%d", ntohs(server.sin_port)); 54231457Sminshall 54331457Sminshall if (whereAPI == 0) { 54431457Sminshall char **ptr, **nextenv; 54531457Sminshall extern char **environ; 54631457Sminshall 54731457Sminshall ptr = environ; 54831457Sminshall nextenv = ourENVlist; 54931457Sminshall while (*ptr) { 55031457Sminshall if (nextenv >= &ourENVlist[highestof(ourENVlist)-1]) { 55131457Sminshall fprintf(stderr, "Too many environmental variables\n"); 55231457Sminshall break; 55331457Sminshall } 55431457Sminshall *nextenv++ = *ptr++; 55531457Sminshall } 55631457Sminshall whereAPI = nextenv++; 55731457Sminshall *nextenv++ = 0; 55831457Sminshall environ = ourENVlist; /* New environment */ 55931457Sminshall } 56031457Sminshall *whereAPI = sockNAME; 56131457Sminshall 56231457Sminshall child_died(); /* Start up signal handler */ 56331457Sminshall shell_active = 1; /* We are running down below */ 56431457Sminshall if (shell_pid = vfork()) { 56531457Sminshall if (shell_pid == -1) { 56631457Sminshall perror("vfork"); 56731457Sminshall (void) close(serversock); 56831457Sminshall } else { 56931465Sminshall state = UNCONNECTED; 57031457Sminshall } 57131455Sminshall } else { /* New process */ 57231455Sminshall register int i; 57331455Sminshall 57431455Sminshall for (i = 3; i < 30; i++) { 57531455Sminshall (void) close(i); 57631455Sminshall } 57731455Sminshall if (argc == 1) { /* Just get a shell */ 57831455Sminshall char *cmdname; 57931457Sminshall extern char *getenv(); 58031455Sminshall 58131455Sminshall cmdname = getenv("SHELL"); 58231455Sminshall execlp(cmdname, cmdname, 0); 58331455Sminshall perror("Exec'ing new shell...\n"); 58431455Sminshall exit(1); 58531455Sminshall } else { 58631455Sminshall execvp(argv[1], &argv[1]); 58731455Sminshall perror("Exec'ing command.\n"); 58831455Sminshall exit(1); 58931455Sminshall } 59031455Sminshall /*NOTREACHED*/ 59131455Sminshall } 59231457Sminshall return shell_active; /* Go back to main loop */ 59331455Sminshall } 594