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 20*31795Sminshall #ifndef FD_SETSIZE 21*31795Sminshall /* 22*31795Sminshall * The following is defined just in case someone should want to run 23*31795Sminshall * this telnet on a 4.2 system. 24*31795Sminshall * 25*31795Sminshall */ 2631455Sminshall 27*31795Sminshall #define FD_SET(n, p) ((p)->fds_bits[0] |= (1<<(n))) 28*31795Sminshall #define FD_CLR(n, p) ((p)->fds_bits[0] &= ~(1<<(n))) 29*31795Sminshall #define FD_ISSET(n, p) ((p)->fds_bits[0] & (1<<(n))) 30*31795Sminshall #define FD_ZERO(p) ((p)->fds_bits[0] = 0) 31*31795Sminshall 32*31795Sminshall #endif 33*31795Sminshall 3431455Sminshall static int shell_pid = 0; 3531455Sminshall 3631457Sminshall static char *ourENVlist[200]; /* Lots of room */ 3731457Sminshall 3831465Sminshall static int 3931465Sminshall sock = -1, /* Connected socket */ 4031465Sminshall serversock; /* Server (listening) socket */ 4131457Sminshall 4231457Sminshall static enum { DEAD, UNCONNECTED, CONNECTED } state; 4331457Sminshall 4431455Sminshall static int 4531463Sminshall storage_location, /* Address we have */ 4631457Sminshall storage_length = 0, /* Length we have */ 4731457Sminshall storage_must_send = 0, /* Storage belongs on other side of wire */ 4831457Sminshall storage_accessed = 0; /* The storage is accessed (so leave alone)! */ 4931457Sminshall 5031503Sminshall static long storage[1000]; 5131457Sminshall 5231463Sminshall static union REGS inputRegs; 5331463Sminshall static struct SREGS inputSregs; 5431457Sminshall 5531463Sminshall 5631463Sminshall static void 5731457Sminshall kill_connection() 5831457Sminshall { 5931465Sminshall state = UNCONNECTED; 6031465Sminshall if (sock != -1) { 6131465Sminshall (void) close(sock); 6231465Sminshall sock = -1; 6331465Sminshall } 6431457Sminshall } 6531457Sminshall 6631457Sminshall 6731457Sminshall static int 6831463Sminshall nextstore() 6931455Sminshall { 7031463Sminshall struct storage_descriptor sd; 7131455Sminshall 7231463Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 7331457Sminshall storage_length = 0; 7431457Sminshall return -1; 7531457Sminshall } 7631463Sminshall storage_length = ntohs(sd.length); 7731463Sminshall storage_location = ntohl(sd.location); 7831463Sminshall if (storage_length > sizeof storage) { 7931457Sminshall fprintf(stderr, "API client tried to send too much storage (%d).\n", 8031457Sminshall storage_length); 8131463Sminshall storage_length = 0; 8231457Sminshall return -1; 8331457Sminshall } 8431511Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage) 8531511Sminshall == -1) { 8631511Sminshall storage_length = 0; 8731511Sminshall return -1; 8831463Sminshall } 8931471Sminshall return 0; 9031457Sminshall } 9131457Sminshall 9231457Sminshall 9331457Sminshall static int 9431457Sminshall doreject(message) 9531457Sminshall char *message; 9631457Sminshall { 9731463Sminshall struct storage_descriptor sd; 9831457Sminshall int length = strlen(message); 9931457Sminshall 10031492Sminshall if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) { 10131457Sminshall return -1; 10231457Sminshall } 10331463Sminshall sd.length = htons(length); 10431465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 10531463Sminshall return -1; 10631463Sminshall } 10731463Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, length, message) == -1) { 10831463Sminshall return -1; 10931463Sminshall } 11031457Sminshall return 0; 11131457Sminshall } 11231457Sminshall 11331457Sminshall 11431455Sminshall /* 11531465Sminshall * doassociate() 11631457Sminshall * 11731457Sminshall * Negotiate with the other side and try to do something. 11831457Sminshall */ 11931457Sminshall 12031457Sminshall static int 12131465Sminshall doassociate() 12231457Sminshall { 12331457Sminshall struct passwd *pwent; 12431457Sminshall char 12531457Sminshall promptbuf[100], 12631457Sminshall buffer[200]; 12731457Sminshall int length; 12831457Sminshall int was; 12931463Sminshall struct storage_descriptor sd; 13031457Sminshall 13131457Sminshall if ((pwent = getpwuid(geteuid())) == 0) { 13231457Sminshall return -1; 13331457Sminshall } 13431457Sminshall sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name); 13531492Sminshall if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) { 13631465Sminshall return -1; 13731465Sminshall } 13831465Sminshall sd.length = htons(strlen(promptbuf)); 13931465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 14031465Sminshall return -1; 14131465Sminshall } 14231465Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf) == -1) { 14331465Sminshall return -1; 14431465Sminshall } 14531465Sminshall sd.length = htons(strlen(pwent->pw_name)); 14631465Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 14731465Sminshall return -1; 14831465Sminshall } 14931465Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, 15031465Sminshall strlen(pwent->pw_name), pwent->pw_name) == -1) { 15131465Sminshall return -1; 15231465Sminshall } 15331492Sminshall if (api_exch_incommand(EXCH_CMD_AUTH) == -1) { 15431457Sminshall return -1; 15531457Sminshall } 15631463Sminshall if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 15731463Sminshall return -1; 15831457Sminshall } 15931463Sminshall sd.length = ntohs(sd.length); 16031463Sminshall if (sd.length > sizeof buffer) { 16131457Sminshall doreject("Password entered was too long"); 16231465Sminshall return -1; 16331457Sminshall } 16431463Sminshall if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) { 16531457Sminshall return -1; 16631457Sminshall } 16731463Sminshall buffer[sd.length] = 0; 16831457Sminshall 16931457Sminshall /* Is this the correct password? */ 17031465Sminshall if (strlen(pwent->pw_name)) { 17131465Sminshall char *ptr; 17231465Sminshall int i; 17331465Sminshall 17431465Sminshall ptr = pwent->pw_name; 17531465Sminshall i = 0; 17631465Sminshall while (i < sd.length) { 17731465Sminshall buffer[i++] ^= *ptr++; 17831465Sminshall if (*ptr == 0) { 17931465Sminshall ptr = pwent->pw_name; 18031465Sminshall } 18131465Sminshall } 18231465Sminshall } 18331457Sminshall if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) == 0) { 18431492Sminshall if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) { 18531465Sminshall return -1; 18631471Sminshall } else { 18731471Sminshall return 1; 18831465Sminshall } 18931457Sminshall } else { 19031457Sminshall doreject("Invalid password"); 19131457Sminshall sleep(10); /* Don't let us do too many of these */ 19231471Sminshall return 0; 19331457Sminshall } 19431457Sminshall } 19531457Sminshall 19631457Sminshall 19731457Sminshall void 19831457Sminshall freestorage() 19931457Sminshall { 20031457Sminshall char buffer[40]; 20131463Sminshall struct storage_descriptor sd; 20231457Sminshall 20331457Sminshall if (storage_accessed) { 20431457Sminshall fprintf(stderr, "Internal error - attempt to free accessed storage.\n"); 20531503Sminshall fprintf(stderr, "(Encountered in file %s at line %d.)\n", 20631457Sminshall __FILE__, __LINE__); 20731457Sminshall quit(); 20831457Sminshall } 20931457Sminshall if (storage_must_send == 0) { 21031457Sminshall return; 21131457Sminshall } 21231457Sminshall storage_must_send = 0; 21331492Sminshall if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) { 21431457Sminshall kill_connection(); 21531457Sminshall return; 21631457Sminshall } 21731463Sminshall sd.length = htons(storage_length); 21831463Sminshall sd.location = htonl(storage_location); 21931463Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) { 22031457Sminshall kill_connection(); 22131457Sminshall return; 22231457Sminshall } 22331511Sminshall if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage) 22431511Sminshall == -1) { 22531511Sminshall kill_connection(); 22631511Sminshall return; 22731463Sminshall } 22831457Sminshall } 22931457Sminshall 23031457Sminshall 23131463Sminshall static int 23231508Sminshall getstorage(address, length, copyin) 23331508Sminshall int 23431508Sminshall address, 23531508Sminshall length, 23631508Sminshall copyin; 23731457Sminshall { 23831463Sminshall struct storage_descriptor sd; 23931457Sminshall char buffer[40]; 24031457Sminshall 24131457Sminshall freestorage(); 24231457Sminshall if (storage_accessed) { 24331457Sminshall fprintf(stderr, 24431457Sminshall "Internal error - attempt to get while storage accessed.\n"); 24531503Sminshall fprintf(stderr, "(Encountered in file %s at line %d.)\n", 24631457Sminshall __FILE__, __LINE__); 24731457Sminshall quit(); 24831457Sminshall } 24931457Sminshall storage_must_send = 0; 25031492Sminshall if (api_exch_outcommand(EXCH_CMD_GIMME) == -1) { 25131457Sminshall kill_connection(); 25231463Sminshall return -1; 25331457Sminshall } 25431471Sminshall storage_location = address; 25531471Sminshall storage_length = length; 25631508Sminshall if (copyin) { 25731508Sminshall sd.location = htonl(storage_location); 25831508Sminshall sd.length = htons(storage_length); 25931508Sminshall if (api_exch_outtype(EXCH_TYPE_STORE_DESC, 26031508Sminshall sizeof sd, (char *)&sd) == -1) { 26131508Sminshall kill_connection(); 26231508Sminshall return -1; 26331508Sminshall } 26431508Sminshall if (api_exch_incommand(EXCH_CMD_HEREIS) == -1) { 26531508Sminshall fprintf(stderr, "Bad data from other side.\n"); 26631508Sminshall fprintf(stderr, "(Encountered at %s, %d.)\n", __FILE__, __LINE__); 26731508Sminshall return -1; 26831508Sminshall } 26931508Sminshall if (nextstore() == -1) { 27031508Sminshall kill_connection(); 27131508Sminshall return -1; 27231508Sminshall } 27331463Sminshall } 27431463Sminshall return 0; 27531457Sminshall } 27631457Sminshall 27731457Sminshall void 27831457Sminshall movetous(local, es, di, length) 27931457Sminshall char 28031457Sminshall *local; 28131457Sminshall int 28231457Sminshall es, 28331457Sminshall di; 28431457Sminshall int 28531457Sminshall length; 28631457Sminshall { 28731457Sminshall if (length > sizeof storage) { 28831457Sminshall fprintf(stderr, "Internal API error - movetous() length too long.\n"); 28931457Sminshall fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); 29031457Sminshall quit(); 29131457Sminshall } else if (length == 0) { 29231457Sminshall return; 29331457Sminshall } 29431508Sminshall getstorage(di, length, 1); 29531463Sminshall memcpy(local, storage+(di-storage_location), length); 29631457Sminshall } 29731457Sminshall 29831457Sminshall void 29931457Sminshall movetothem(es, di, local, length) 30031457Sminshall int 30131457Sminshall es, 30231457Sminshall di; 30331457Sminshall char 30431457Sminshall *local; 30531457Sminshall int 30631457Sminshall length; 30731457Sminshall { 30831457Sminshall if (length > sizeof storage) { 30931457Sminshall fprintf(stderr, "Internal API error - movetothem() length too long.\n"); 31031457Sminshall fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__); 31131457Sminshall quit(); 31231457Sminshall } else if (length == 0) { 31331457Sminshall return; 31431457Sminshall } 31531457Sminshall freestorage(); 31631457Sminshall memcpy((char *)storage, local, length); 31731457Sminshall storage_length = length; 31831463Sminshall storage_location = di; 31931457Sminshall storage_must_send = 1; 32031457Sminshall } 32131457Sminshall 32231457Sminshall 32331457Sminshall char * 32431508Sminshall access_api(location, length, copyin) 32531457Sminshall int 32631457Sminshall location, 32731508Sminshall length, 32831508Sminshall copyin; /* Do we need to copy in initially? */ 32931457Sminshall { 33031457Sminshall if (storage_accessed) { 33131457Sminshall fprintf(stderr, "Internal error - storage accessed twice\n"); 33231503Sminshall fprintf(stderr, "(Encountered in file %s, line %d.)\n", 33331457Sminshall __FILE__, __LINE__); 33431457Sminshall quit(); 33531457Sminshall } else if (length != 0) { 33631457Sminshall freestorage(); 33731508Sminshall getstorage(location, length, copyin); 33831503Sminshall storage_accessed = 1; 33931457Sminshall } 34031457Sminshall return (char *) storage; 34131457Sminshall } 34231457Sminshall 34331508Sminshall unaccess_api(location, local, length, copyout) 34431457Sminshall int location; 34531457Sminshall char *local; 34631457Sminshall int length; 34731457Sminshall { 34831457Sminshall if (storage_accessed == 0) { 34931457Sminshall fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n"); 35031503Sminshall fprintf(stderr, "(Encountered in file %s, line %d.)\n", 35131457Sminshall __FILE__, __LINE__); 35231457Sminshall quit(); 35331457Sminshall } 35431457Sminshall storage_accessed = 0; 35531508Sminshall storage_must_send = copyout; /* if needs to go back */ 35631457Sminshall } 35731457Sminshall 35831465Sminshall /* 35931465Sminshall * Accept a connection from an API client, aborting if the child dies. 36031465Sminshall */ 36131457Sminshall 36231465Sminshall static int 36331465Sminshall doconnect() 36431465Sminshall { 36531465Sminshall fd_set fdset; 36631465Sminshall int i; 36731465Sminshall 36831465Sminshall sock = -1; 36931465Sminshall FD_ZERO(&fdset); 37031465Sminshall while (shell_active && (sock == -1)) { 37131465Sminshall FD_SET(serversock, &fdset); 37231465Sminshall if ((i = select(serversock+1, &fdset, 0, 0, 0)) < 0) { 37331465Sminshall if (errno = EINTR) { 37431465Sminshall continue; 37531465Sminshall } else { 37631465Sminshall perror("in select waiting for API connection"); 37731465Sminshall return -1; 37831465Sminshall } 37931465Sminshall } else { 38031465Sminshall i = accept(serversock, 0, 0); 38131465Sminshall if (i == -1) { 38231465Sminshall perror("accepting API connection"); 38331465Sminshall return -1; 38431465Sminshall } 38531465Sminshall sock = i; 38631465Sminshall } 38731465Sminshall } 38831465Sminshall /* If the process has already exited, we may need to close */ 38931465Sminshall if ((shell_active == 0) && (sock != -1)) { 39031465Sminshall (void) close(sock); 39131465Sminshall sock = -1; 39231465Sminshall setcommandmode(); /* In case child_died sneaked in */ 39331465Sminshall } 39431465Sminshall } 39531465Sminshall 39631457Sminshall /* 39731455Sminshall * shell_continue() actually runs the command, and looks for API 39831455Sminshall * requests coming back in. 39931455Sminshall * 40031455Sminshall * We are called from the main loop in telnet.c. 40131455Sminshall */ 40231455Sminshall 40331455Sminshall int 40431455Sminshall shell_continue() 40531455Sminshall { 40631492Sminshall int i; 40731492Sminshall 40831457Sminshall switch (state) { 40931457Sminshall case DEAD: 41031457Sminshall pause(); /* Nothing to do */ 41131457Sminshall break; 41231457Sminshall case UNCONNECTED: 41331465Sminshall if (doconnect() == -1) { 41431457Sminshall kill_connection(); 41531465Sminshall return -1; 41631465Sminshall } 41731492Sminshall if (api_exch_init(sock, "server") == -1) { 41831465Sminshall return -1; 41931465Sminshall } 42031465Sminshall while (state == UNCONNECTED) { 42131492Sminshall if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) { 42231457Sminshall kill_connection(); 42331465Sminshall return -1; 42431465Sminshall } else { 42531465Sminshall switch (doassociate()) { 42631465Sminshall case -1: 42731465Sminshall kill_connection(); 42831465Sminshall return -1; 42931465Sminshall case 0: 43031465Sminshall break; 43131465Sminshall case 1: 43231465Sminshall state = CONNECTED; 43331465Sminshall } 43431457Sminshall } 43531457Sminshall } 43631457Sminshall break; 43731457Sminshall case CONNECTED: 43831492Sminshall switch (i = api_exch_nextcommand()) { 43931492Sminshall case EXCH_CMD_REQUEST: 44031492Sminshall if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs, 44131492Sminshall (char *)&inputRegs) == -1) { 44231463Sminshall kill_connection(); 44331492Sminshall } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs, 44431492Sminshall (char *)&inputSregs) == -1) { 44531463Sminshall kill_connection(); 44631492Sminshall } else if (nextstore() == -1) { 44731463Sminshall kill_connection(); 44831492Sminshall } else { 44931492Sminshall handle_api(&inputRegs, &inputSregs); 45031492Sminshall freestorage(); /* Send any storage back */ 45131492Sminshall if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) { 45231492Sminshall kill_connection(); 45331492Sminshall } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs, 45431492Sminshall (char *)&inputRegs) == -1) { 45531492Sminshall kill_connection(); 45631492Sminshall } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs, 45731492Sminshall (char *)&inputSregs) == -1) { 45831492Sminshall kill_connection(); 45931492Sminshall } 46031492Sminshall /* Done, and it all worked! */ 46131463Sminshall } 46231492Sminshall break; 46331492Sminshall case EXCH_CMD_DISASSOCIATE: 46431492Sminshall kill_connection(); 46531492Sminshall break; 46631492Sminshall default: 46731503Sminshall if (i != -1) { 46831503Sminshall fprintf(stderr, 46931503Sminshall "Looking for a REQUEST or DISASSOCIATE command\n"); 47031503Sminshall fprintf(stderr, "\treceived 0x%02x.\n", i); 47131503Sminshall } 47231492Sminshall kill_connection(); 47331503Sminshall break; 47431457Sminshall } 47531457Sminshall } 47631455Sminshall return shell_active; 47731455Sminshall } 47831455Sminshall 47931455Sminshall 48031463Sminshall static int 48131463Sminshall child_died() 48231463Sminshall { 48331463Sminshall union wait *status; 48431463Sminshall register int pid; 48531463Sminshall 48631463Sminshall while ((pid = wait3(&status, WNOHANG, 0)) > 0) { 48731463Sminshall if (pid == shell_pid) { 48831463Sminshall char inputbuffer[100]; 48931463Sminshall 49031463Sminshall shell_active = 0; 49131463Sminshall if (sock != -1) { 49231463Sminshall (void) close(sock); 49331463Sminshall sock = -1; 49431463Sminshall } 49531471Sminshall printf("[Hit return to continue]"); 49631471Sminshall fflush(stdout); 49731471Sminshall (void) gets(inputbuffer); 49831465Sminshall setconnmode(); 49931465Sminshall ConnectScreen(); /* Turn screen on (if need be) */ 50031465Sminshall (void) close(serversock); 50131463Sminshall } 50231463Sminshall } 50331463Sminshall signal(SIGCHLD, child_died); 50431463Sminshall } 50531463Sminshall 50631463Sminshall 50731455Sminshall /* 50831455Sminshall * Called from telnet.c to fork a lower command.com. We 50931455Sminshall * use the spint... routines so that we can pick up 51031455Sminshall * interrupts generated by application programs. 51131455Sminshall */ 51231455Sminshall 51331455Sminshall 51431455Sminshall int 51531455Sminshall shell(argc,argv) 51631455Sminshall int argc; 51731455Sminshall char *argv[]; 51831455Sminshall { 51931465Sminshall int length; 52031457Sminshall struct sockaddr_in server; 52131457Sminshall char sockNAME[100]; 52231457Sminshall static char **whereAPI = 0; 52331457Sminshall 52431457Sminshall /* First, create the socket which will be connected to */ 52531457Sminshall serversock = socket(AF_INET, SOCK_STREAM, 0); 52631457Sminshall if (serversock < 0) { 52731457Sminshall perror("opening API socket"); 52831457Sminshall return 0; 52931457Sminshall } 53031457Sminshall server.sin_family = AF_INET; 53131457Sminshall server.sin_addr.s_addr = INADDR_ANY; 53231457Sminshall server.sin_port = 0; 53331457Sminshall if (bind(serversock, &server, sizeof server) < 0) { 53431457Sminshall perror("binding API socket"); 53531457Sminshall return 0; 53631457Sminshall } 53731457Sminshall length = sizeof server; 53831457Sminshall if (getsockname(serversock, &server, &length) < 0) { 53931457Sminshall perror("getting API socket name"); 54031457Sminshall (void) close(serversock); 54131457Sminshall } 54231457Sminshall listen(serversock, 1); 54331457Sminshall /* Get name to advertise in address list */ 54431457Sminshall strcpy(sockNAME, "API3270="); 54531457Sminshall gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME)); 54631457Sminshall if (strlen(sockNAME) > (sizeof sockNAME-10)) { 54731457Sminshall fprintf(stderr, "Local hostname too large; using 'localhost'.\n"); 54831457Sminshall strcpy(sockNAME, "localhost"); 54931457Sminshall } 55031457Sminshall sprintf(sockNAME+strlen(sockNAME), ":%d", ntohs(server.sin_port)); 55131457Sminshall 55231457Sminshall if (whereAPI == 0) { 55331457Sminshall char **ptr, **nextenv; 55431457Sminshall extern char **environ; 55531457Sminshall 55631457Sminshall ptr = environ; 55731457Sminshall nextenv = ourENVlist; 55831457Sminshall while (*ptr) { 55931457Sminshall if (nextenv >= &ourENVlist[highestof(ourENVlist)-1]) { 56031457Sminshall fprintf(stderr, "Too many environmental variables\n"); 56131457Sminshall break; 56231457Sminshall } 56331457Sminshall *nextenv++ = *ptr++; 56431457Sminshall } 56531457Sminshall whereAPI = nextenv++; 56631457Sminshall *nextenv++ = 0; 56731457Sminshall environ = ourENVlist; /* New environment */ 56831457Sminshall } 56931457Sminshall *whereAPI = sockNAME; 57031457Sminshall 57131457Sminshall child_died(); /* Start up signal handler */ 57231457Sminshall shell_active = 1; /* We are running down below */ 57331457Sminshall if (shell_pid = vfork()) { 57431457Sminshall if (shell_pid == -1) { 57531457Sminshall perror("vfork"); 57631457Sminshall (void) close(serversock); 57731457Sminshall } else { 57831465Sminshall state = UNCONNECTED; 57931457Sminshall } 58031455Sminshall } else { /* New process */ 58131455Sminshall register int i; 58231455Sminshall 58331455Sminshall for (i = 3; i < 30; i++) { 58431455Sminshall (void) close(i); 58531455Sminshall } 58631455Sminshall if (argc == 1) { /* Just get a shell */ 58731455Sminshall char *cmdname; 58831457Sminshall extern char *getenv(); 58931455Sminshall 59031455Sminshall cmdname = getenv("SHELL"); 59131455Sminshall execlp(cmdname, cmdname, 0); 59231455Sminshall perror("Exec'ing new shell...\n"); 59331455Sminshall exit(1); 59431455Sminshall } else { 59531455Sminshall execvp(argv[1], &argv[1]); 59631455Sminshall perror("Exec'ing command.\n"); 59731455Sminshall exit(1); 59831455Sminshall } 59931455Sminshall /*NOTREACHED*/ 60031455Sminshall } 60131457Sminshall return shell_active; /* Go back to main loop */ 60231455Sminshall } 603