Annotation of 43BSDReno/usr.bin/tn3270/sys_curses/system.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1988 Regents of the University of California.
                      3:  * All rights reserved.
                      4:  *
                      5:  * Redistribution and use in source and binary forms are permitted
                      6:  * provided that the above copyright notice and this paragraph are
                      7:  * duplicated in all such forms and that any documentation,
                      8:  * advertising materials, and other materials related to such
                      9:  * distribution and use acknowledge that the software was developed
                     10:  * by the University of California, Berkeley.  The name of the
                     11:  * University may not be used to endorse or promote products derived
                     12:  * from this software without specific prior written permission.
                     13:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
                     14:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
                     15:  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
                     16:  */
                     17: 
                     18: #ifndef lint
                     19: static char sccsid[] = "@(#)system.c   4.3 (Berkeley) 9/2/89";
                     20: #endif /* not lint */
                     21: 
                     22: #include <sys/types.h>
                     23: 
                     24: #if     defined(pyr)
                     25: #define fd_set fdset_t
                     26: #endif  /* defined(pyr) */
                     27: 
                     28: /*
                     29:  * Wouldn't it be nice if these REALLY were in <sys/inode.h>?  Or,
                     30:  * equivalently, if <sys/inode.h> REALLY existed?
                     31:  */
                     32: #define        IREAD   00400
                     33: #define        IWRITE  00200
                     34: 
                     35: #include <sys/file.h>
                     36: #include <sys/time.h>
                     37: #include <sys/socket.h>
                     38: #include <netinet/in.h>
                     39: #include <sys/wait.h>
                     40: 
                     41: #include <errno.h>
                     42: extern int errno;
                     43: 
                     44: #include <netdb.h>
                     45: #include <signal.h>
                     46: #include <stdio.h>
                     47: #include <pwd.h>
                     48: 
                     49: #include "../general/general.h"
                     50: #include "../ctlr/api.h"
                     51: #include "../api/api_exch.h"
                     52: 
                     53: #include "../general/globals.h"
                     54: 
                     55: #ifndef        FD_SETSIZE
                     56: /*
                     57:  * The following is defined just in case someone should want to run
                     58:  * this telnet on a 4.2 system.
                     59:  *
                     60:  */
                     61: 
                     62: #define        FD_SET(n, p)    ((p)->fds_bits[0] |= (1<<(n)))
                     63: #define        FD_CLR(n, p)    ((p)->fds_bits[0] &= ~(1<<(n)))
                     64: #define        FD_ISSET(n, p)  ((p)->fds_bits[0] & (1<<(n)))
                     65: #define FD_ZERO(p)     ((p)->fds_bits[0] = 0)
                     66: 
                     67: #endif
                     68: 
                     69: static int shell_pid = 0;
                     70: static char key[50];                   /* Actual key */
                     71: static char *keyname;                  /* Name of file with key in it */
                     72: 
                     73: static char *ourENVlist[200];          /* Lots of room */
                     74: 
                     75: static int
                     76:     sock = -1,                         /* Connected socket */
                     77:     serversock;                                /* Server (listening) socket */
                     78: 
                     79: static enum { DEAD, UNCONNECTED, CONNECTED } state;
                     80: 
                     81: static long
                     82:     storage_location;          /* Address we have */
                     83: static short
                     84:     storage_length = 0;                /* Length we have */
                     85: static int
                     86:     storage_must_send = 0,     /* Storage belongs on other side of wire */
                     87:     storage_accessed = 0;      /* The storage is accessed (so leave alone)! */
                     88: 
                     89: static long storage[1000];
                     90: 
                     91: static union REGS inputRegs;
                     92: static struct SREGS inputSregs;
                     93: 
                     94: extern int apitrace;
                     95: 
                     96: static void
                     97: kill_connection()
                     98: {
                     99:     state = UNCONNECTED;
                    100:     if (sock != -1) {
                    101:        (void) close(sock);
                    102:        sock = -1;
                    103:     }
                    104: }
                    105: 
                    106: 
                    107: static int
                    108: nextstore()
                    109: {
                    110:     struct storage_descriptor sd;
                    111: 
                    112:     if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
                    113:        storage_length = 0;
                    114:        return -1;
                    115:     }
                    116:     storage_length = sd.length;
                    117:     storage_location = sd.location;
                    118:     if (storage_length > sizeof storage) {
                    119:        fprintf(stderr, "API client tried to send too much storage (%d).\n",
                    120:                storage_length);
                    121:        storage_length = 0;
                    122:        return -1;
                    123:     }
                    124:     if (api_exch_intype(EXCH_TYPE_BYTES, storage_length, (char *)storage)
                    125:                                                        == -1) {
                    126:        storage_length = 0;
                    127:        return -1;
                    128:     }
                    129:     return 0;
                    130: }
                    131: 
                    132: 
                    133: static int
                    134: doreject(message)
                    135: char   *message;
                    136: {
                    137:     struct storage_descriptor sd;
                    138:     int length = strlen(message);
                    139: 
                    140:     if (api_exch_outcommand(EXCH_CMD_REJECTED) == -1) {
                    141:        return -1;
                    142:     }
                    143:     sd.length = length;
                    144:     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
                    145:        return -1;
                    146:     }
                    147:     if (api_exch_outtype(EXCH_TYPE_BYTES, length, message) == -1) {
                    148:        return -1;
                    149:     }
                    150:     return 0;
                    151: }
                    152: 
                    153: 
                    154: /*
                    155:  * doassociate()
                    156:  *
                    157:  * Negotiate with the other side and try to do something.
                    158:  *
                    159:  * Returns:
                    160:  *
                    161:  *     -1:     Error in processing
                    162:  *      0:     Invalid password entered
                    163:  *      1:     Association OK
                    164:  */
                    165: 
                    166: static int
                    167: doassociate()
                    168: {
                    169:     struct passwd *pwent;
                    170:     char
                    171:        promptbuf[100],
                    172:        buffer[200];
                    173:     struct storage_descriptor sd;
                    174:     extern char *crypt();
                    175: 
                    176:     if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
                    177:        return -1;
                    178:     }
                    179:     sd.length = sd.length;
                    180:     if (sd.length > sizeof buffer) {
                    181:        doreject("(internal error) Authentication key too long");
                    182:        return -1;
                    183:     }
                    184:     if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
                    185:        return -1;
                    186:     }
                    187:     buffer[sd.length] = 0;
                    188: 
                    189:     if (strcmp(buffer, key) != 0) {
                    190: #if    (!defined(sun)) || defined(BSD) && (BSD >= 43)
                    191:        extern uid_t geteuid();
                    192: #endif /* (!defined(sun)) || defined(BSD) && (BSD >= 43) */
                    193: 
                    194:        if ((pwent = getpwuid((int)geteuid())) == 0) {
                    195:            return -1;
                    196:        }
                    197:        sprintf(promptbuf, "Enter password for user %s:", pwent->pw_name);
                    198:        if (api_exch_outcommand(EXCH_CMD_SEND_AUTH) == -1) {
                    199:            return -1;
                    200:        }
                    201:        sd.length = strlen(promptbuf);
                    202:        if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
                    203:                                                                        == -1) {
                    204:            return -1;
                    205:        }
                    206:        if (api_exch_outtype(EXCH_TYPE_BYTES, strlen(promptbuf), promptbuf)
                    207:                                                                        == -1) {
                    208:            return -1;
                    209:        }
                    210:        sd.length = strlen(pwent->pw_name);
                    211:        if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
                    212:                                                                        == -1) {
                    213:            return -1;
                    214:        }
                    215:        if (api_exch_outtype(EXCH_TYPE_BYTES,
                    216:                            strlen(pwent->pw_name), pwent->pw_name) == -1) {
                    217:            return -1;
                    218:        }
                    219:        if (api_exch_incommand(EXCH_CMD_AUTH) == -1) {
                    220:            return -1;
                    221:        }
                    222:        if (api_exch_intype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd)
                    223:                                                                        == -1) {
                    224:            return -1;
                    225:        }
                    226:        sd.length = sd.length;
                    227:        if (sd.length > sizeof buffer) {
                    228:            doreject("Password entered was too long");
                    229:            return -1;
                    230:        }
                    231:        if (api_exch_intype(EXCH_TYPE_BYTES, sd.length, buffer) == -1) {
                    232:            return -1;
                    233:        }
                    234:        buffer[sd.length] = 0;
                    235: 
                    236:        /* Is this the correct password? */
                    237:        if (strlen(pwent->pw_name)) {
                    238:            char *ptr;
                    239:            int i;
                    240: 
                    241:            ptr = pwent->pw_name;
                    242:            i = 0;
                    243:            while (i < sd.length) {
                    244:                buffer[i++] ^= *ptr++;
                    245:                if (*ptr == 0) {
                    246:                    ptr = pwent->pw_name;
                    247:                }
                    248:            }
                    249:        }
                    250:        if (strcmp(crypt(buffer, pwent->pw_passwd), pwent->pw_passwd) != 0) {
                    251:            doreject("Invalid password");
                    252:            sleep(10);          /* Don't let us do too many of these */
                    253:            return 0;
                    254:        }
                    255:     }
                    256:     if (api_exch_outcommand(EXCH_CMD_ASSOCIATED) == -1) {
                    257:        return -1;
                    258:     } else {
                    259:        return 1;
                    260:     }
                    261: }
                    262: 
                    263: 
                    264: void
                    265: freestorage()
                    266: {
                    267:     struct storage_descriptor sd;
                    268: 
                    269:     if (storage_accessed) {
                    270:        fprintf(stderr, "Internal error - attempt to free accessed storage.\n");
                    271:        fprintf(stderr, "(Encountered in file %s at line %d.)\n",
                    272:                        __FILE__, __LINE__);
                    273:        quit();
                    274:     }
                    275:     if (storage_must_send == 0) {
                    276:        return;
                    277:     }
                    278:     storage_must_send = 0;
                    279:     if (api_exch_outcommand(EXCH_CMD_HEREIS) == -1) {
                    280:        kill_connection();
                    281:        return;
                    282:     }
                    283:     sd.length = storage_length;
                    284:     sd.location = storage_location;
                    285:     if (api_exch_outtype(EXCH_TYPE_STORE_DESC, sizeof sd, (char *)&sd) == -1) {
                    286:        kill_connection();
                    287:        return;
                    288:     }
                    289:     if (api_exch_outtype(EXCH_TYPE_BYTES, storage_length, (char *)storage)
                    290:                                                            == -1) {
                    291:        kill_connection();
                    292:        return;
                    293:     }
                    294: }
                    295: 
                    296: 
                    297: static int
                    298: getstorage(address, length, copyin)
                    299: long
                    300:     address;
                    301: int
                    302:     length,
                    303:     copyin;
                    304: {
                    305:     struct storage_descriptor sd;
                    306: 
                    307:     freestorage();
                    308:     if (storage_accessed) {
                    309:        fprintf(stderr,
                    310:                "Internal error - attempt to get while storage accessed.\n");
                    311:        fprintf(stderr, "(Encountered in file %s at line %d.)\n",
                    312:                        __FILE__, __LINE__);
                    313:        quit();
                    314:     }
                    315:     storage_must_send = 0;
                    316:     if (api_exch_outcommand(EXCH_CMD_GIMME) == -1) {
                    317:        kill_connection();
                    318:        return -1;
                    319:     }
                    320:     storage_location = address;
                    321:     storage_length = length;
                    322:     if (copyin) {
                    323:        sd.location = (long)storage_location;
                    324:        sd.length = storage_length;
                    325:        if (api_exch_outtype(EXCH_TYPE_STORE_DESC,
                    326:                                        sizeof sd, (char *)&sd) == -1) {
                    327:            kill_connection();
                    328:            return -1;
                    329:        }
                    330:        if (api_exch_incommand(EXCH_CMD_HEREIS) == -1) {
                    331:            fprintf(stderr, "Bad data from other side.\n");
                    332:            fprintf(stderr, "(Encountered at %s, %d.)\n", __FILE__, __LINE__);
                    333:            return -1;
                    334:        }
                    335:        if (nextstore() == -1) {
                    336:            kill_connection();
                    337:            return -1;
                    338:        }
                    339:     }
                    340:     return 0;
                    341: }
                    342: 
                    343: /*ARGSUSED*/
                    344: void
                    345: movetous(local, es, di, length)
                    346: char
                    347:     *local;
                    348: unsigned int
                    349:     es,
                    350:     di;
                    351: int
                    352:     length;
                    353: {
                    354:     long where = SEG_OFF_BACK(es, di);
                    355: 
                    356:     if (length > sizeof storage) {
                    357:        fprintf(stderr, "Internal API error - movetous() length too long.\n");
                    358:        fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__);
                    359:        quit();
                    360:     } else if (length == 0) {
                    361:        return;
                    362:     }
                    363:     getstorage(where, length, 1);
                    364:     memcpy(local, (char *)(storage+((where-storage_location))), length);
                    365:     if (apitrace) {
                    366:        Dump('(', local, length);
                    367:     }
                    368: }
                    369: 
                    370: /*ARGSUSED*/
                    371: void
                    372: movetothem(es, di, local, length)
                    373: unsigned int
                    374:     es,
                    375:     di;
                    376: char
                    377:     *local;
                    378: int
                    379:     length;
                    380: {
                    381:     long where = SEG_OFF_BACK(es, di);
                    382: 
                    383:     if (length > sizeof storage) {
                    384:        fprintf(stderr, "Internal API error - movetothem() length too long.\n");
                    385:        fprintf(stderr, "(detected in file %s, line %d)\n", __FILE__, __LINE__);
                    386:        quit();
                    387:     } else if (length == 0) {
                    388:        return;
                    389:     }
                    390:     freestorage();
                    391:     memcpy((char *)storage, local, length);
                    392:     if (apitrace) {
                    393:        Dump(')', local, length);
                    394:     }
                    395:     storage_length = length;
                    396:     storage_location = where;
                    397:     storage_must_send = 1;
                    398: }
                    399: 
                    400: 
                    401: char *
                    402: access_api(location, length, copyin)
                    403: char *
                    404:     location;
                    405: int
                    406:     length,
                    407:     copyin;                    /* Do we need to copy in initially? */
                    408: {
                    409:     if (storage_accessed) {
                    410:        fprintf(stderr, "Internal error - storage accessed twice\n");
                    411:        fprintf(stderr, "(Encountered in file %s, line %d.)\n",
                    412:                                __FILE__, __LINE__);
                    413:        quit();
                    414:     } else if (length != 0) {
                    415:        freestorage();
                    416:        getstorage((long)location, length, copyin);
                    417:        storage_accessed = 1;
                    418:     }
                    419:     return (char *) storage;
                    420: }
                    421: 
                    422: /*ARGSUSED*/
                    423: void
                    424: unaccess_api(location, local, length, copyout)
                    425: char   *location;
                    426: char   *local;
                    427: int    length;
                    428: int    copyout;
                    429: {
                    430:     if (storage_accessed == 0) {
                    431:        fprintf(stderr, "Internal error - unnecessary unaccess_api call.\n");
                    432:        fprintf(stderr, "(Encountered in file %s, line %d.)\n",
                    433:                        __FILE__, __LINE__);
                    434:        quit();
                    435:     }
                    436:     storage_accessed = 0;
                    437:     storage_must_send = copyout;       /* if needs to go back */
                    438: }
                    439: 
                    440: /*
                    441:  * Accept a connection from an API client, aborting if the child dies.
                    442:  */
                    443: 
                    444: static int
                    445: doconnect()
                    446: {
                    447:     fd_set fdset;
                    448:     int i;
                    449: 
                    450:     sock = -1;
                    451:     FD_ZERO(&fdset);
                    452:     while (shell_active && (sock == -1)) {
                    453:        FD_SET(serversock, &fdset);
                    454:        if ((i = select(serversock+1, &fdset,
                    455:                    (fd_set *)0, (fd_set *)0, (struct timeval *)0)) < 0) {
                    456:            if (errno = EINTR) {
                    457:                continue;
                    458:            } else {
                    459:                perror("in select waiting for API connection");
                    460:                return -1;
                    461:            }
                    462:        } else {
                    463:            i = accept(serversock, (struct sockaddr *)0, (int *)0);
                    464:            if (i == -1) {
                    465:                perror("accepting API connection");
                    466:                return -1;
                    467:            }
                    468:            sock = i;
                    469:        }
                    470:     }
                    471:     /* If the process has already exited, we may need to close */
                    472:     if ((shell_active == 0) && (sock != -1)) {
                    473:        extern void setcommandmode();
                    474: 
                    475:        (void) close(sock);
                    476:        sock = -1;
                    477:        setcommandmode();       /* In case child_died sneaked in */
                    478:     }
                    479:     return 0;
                    480: }
                    481: 
                    482: /*
                    483:  * shell_continue() actually runs the command, and looks for API
                    484:  * requests coming back in.
                    485:  *
                    486:  * We are called from the main loop in telnet.c.
                    487:  */
                    488: 
                    489: int
                    490: shell_continue()
                    491: {
                    492:     int i;
                    493: 
                    494:     switch (state) {
                    495:     case DEAD:
                    496:        pause();                        /* Nothing to do */
                    497:        break;
                    498:     case UNCONNECTED:
                    499:        if (doconnect() == -1) {
                    500:            kill_connection();
                    501:            return -1;
                    502:        }
                    503:        /* At this point, it is possible that we've gone away */
                    504:        if (shell_active == 0) {
                    505:            kill_connection();
                    506:            return -1;
                    507:        }
                    508:        if (api_exch_init(sock, "server") == -1) {
                    509:            return -1;
                    510:        }
                    511:        while (state == UNCONNECTED) {
                    512:            if (api_exch_incommand(EXCH_CMD_ASSOCIATE) == -1) {
                    513:                kill_connection();
                    514:                return -1;
                    515:            } else {
                    516:                switch (doassociate()) {
                    517:                case -1:
                    518:                    kill_connection();
                    519:                    return -1;
                    520:                case 0:
                    521:                    break;
                    522:                case 1:
                    523:                    state = CONNECTED;
                    524:                }
                    525:            }
                    526:        }
                    527:        break;
                    528:     case CONNECTED:
                    529:        switch (i = api_exch_nextcommand()) {
                    530:        case EXCH_CMD_REQUEST:
                    531:            if (api_exch_intype(EXCH_TYPE_REGS, sizeof inputRegs,
                    532:                                    (char *)&inputRegs) == -1) {
                    533:                kill_connection();
                    534:            } else if (api_exch_intype(EXCH_TYPE_SREGS, sizeof inputSregs,
                    535:                                    (char *)&inputSregs) == -1) {
                    536:                kill_connection();
                    537:            } else if (nextstore() == -1) {
                    538:                kill_connection();
                    539:            } else {
                    540:                handle_api(&inputRegs, &inputSregs);
                    541:                freestorage();                  /* Send any storage back */
                    542:                if (api_exch_outcommand(EXCH_CMD_REPLY) == -1) {
                    543:                    kill_connection();
                    544:                } else if (api_exch_outtype(EXCH_TYPE_REGS, sizeof inputRegs,
                    545:                                    (char *)&inputRegs) == -1) {
                    546:                    kill_connection();
                    547:                } else if (api_exch_outtype(EXCH_TYPE_SREGS, sizeof inputSregs,
                    548:                                    (char *)&inputSregs) == -1) {
                    549:                    kill_connection();
                    550:                }
                    551:                /* Done, and it all worked! */
                    552:            }
                    553:            break;
                    554:        case EXCH_CMD_DISASSOCIATE:
                    555:            kill_connection();
                    556:            break;
                    557:        default:
                    558:            if (i != -1) {
                    559:                fprintf(stderr,
                    560:                        "Looking for a REQUEST or DISASSOCIATE command\n");
                    561:                fprintf(stderr, "\treceived 0x%02x.\n", i);
                    562:            }
                    563:            kill_connection();
                    564:            break;
                    565:        }
                    566:     }
                    567:     return shell_active;
                    568: }
                    569: 
                    570: 
                    571: static int
                    572: child_died()
                    573: {
                    574:     union wait status;
                    575:     register int pid;
                    576: 
                    577:     while ((pid = wait3(&status, WNOHANG, (struct rusage *)0)) > 0) {
                    578:        if (pid == shell_pid) {
                    579:            char inputbuffer[100];
                    580:            extern void setconnmode();
                    581:            extern void ConnectScreen();
                    582: 
                    583:            shell_active = 0;
                    584:            if (sock != -1) {
                    585:                (void) close(sock);
                    586:                sock = -1;
                    587:            }
                    588:            printf("[Hit return to continue]");
                    589:            fflush(stdout);
                    590:            (void) gets(inputbuffer);
                    591:            setconnmode();
                    592:            ConnectScreen();    /* Turn screen on (if need be) */
                    593:            (void) close(serversock);
                    594:            (void) unlink(keyname);
                    595:        }
                    596:     }
                    597:     signal(SIGCHLD, child_died);
                    598: }
                    599: 
                    600: 
                    601: /*
                    602:  * Called from telnet.c to fork a lower command.com.  We
                    603:  * use the spint... routines so that we can pick up
                    604:  * interrupts generated by application programs.
                    605:  */
                    606: 
                    607: 
                    608: int
                    609: shell(argc,argv)
                    610: int    argc;
                    611: char   *argv[];
                    612: {
                    613:     int length;
                    614:     struct sockaddr_in server;
                    615:     char sockNAME[100];
                    616:     static char **whereAPI = 0;
                    617:     int fd;
                    618:     struct timeval tv;
                    619:     long ikey;
                    620:     extern long random();
                    621:     extern char *mktemp();
                    622:     extern char *strcpy();
                    623: 
                    624:     /* First, create verification file. */
                    625:     do {
                    626:        keyname = mktemp("/tmp/apiXXXXXX");
                    627:        fd = open(keyname, O_RDWR|O_CREAT|O_EXCL, IREAD|IWRITE);
                    628:     } while ((fd == -1) && (errno == EEXIST));
                    629: 
                    630:     if (fd == -1) {
                    631:        perror("open");
                    632:        return 0;
                    633:     }
                    634: 
                    635:     /* Now, get seed for random */
                    636: 
                    637:     if (gettimeofday(&tv, (struct timezone *)0) == -1) {
                    638:        perror("gettimeofday");
                    639:        return 0;
                    640:     }
                    641:     srandom(tv.tv_usec);               /* seed random number generator */
                    642:     do {
                    643:        ikey = random();
                    644:     } while (ikey == 0);
                    645:     sprintf(key, "%lu\n", (unsigned long) ikey);
                    646:     if (write(fd, key, strlen(key)) != strlen(key)) {
                    647:        perror("write");
                    648:        return 0;
                    649:     }
                    650:     key[strlen(key)-1] = 0;            /* Get rid of newline */
                    651: 
                    652:     if (close(fd) == -1) {
                    653:        perror("close");
                    654:        return 0;
                    655:     }
                    656: 
                    657:     /* Next, create the socket which will be connected to */
                    658:     serversock = socket(AF_INET, SOCK_STREAM, 0);
                    659:     if (serversock < 0) {
                    660:        perror("opening API socket");
                    661:        return 0;
                    662:     }
                    663:     server.sin_family = AF_INET;
                    664:     server.sin_addr.s_addr = INADDR_ANY;
                    665:     server.sin_port = 0;
                    666:     if (bind(serversock, (struct sockaddr *)&server, sizeof server) < 0) {
                    667:        perror("binding API socket");
                    668:        return 0;
                    669:     }
                    670:     length = sizeof server;
                    671:     if (getsockname(serversock, (struct sockaddr *)&server, &length) < 0) {
                    672:        perror("getting API socket name");
                    673:        (void) close(serversock);
                    674:     }
                    675:     listen(serversock, 1);
                    676:     /* Get name to advertise in address list */
                    677:     strcpy(sockNAME, "API3270=");
                    678:     gethostname(sockNAME+strlen(sockNAME), sizeof sockNAME-strlen(sockNAME));
                    679:     if (strlen(sockNAME) > (sizeof sockNAME-(10+strlen(keyname)))) {
                    680:        fprintf(stderr, "Local hostname too large; using 'localhost'.\n");
                    681:        strcpy(sockNAME, "localhost");
                    682:     }
                    683:     sprintf(sockNAME+strlen(sockNAME), ":%u", ntohs(server.sin_port));
                    684:     sprintf(sockNAME+strlen(sockNAME), ":%s", keyname);
                    685: 
                    686:     if (whereAPI == 0) {
                    687:        char **ptr, **nextenv;
                    688:        extern char **environ;
                    689: 
                    690:        ptr = environ;
                    691:        nextenv = ourENVlist;
                    692:        while (*ptr) {
                    693:            if (nextenv >= &ourENVlist[highestof(ourENVlist)-1]) {
                    694:                fprintf(stderr, "Too many environmental variables\n");
                    695:                break;
                    696:            }
                    697:            *nextenv++ = *ptr++;
                    698:        }
                    699:        whereAPI = nextenv++;
                    700:        *nextenv++ = 0;
                    701:        environ = ourENVlist;           /* New environment */
                    702:     }
                    703:     *whereAPI = sockNAME;
                    704: 
                    705:     child_died();                      /* Start up signal handler */
                    706:     shell_active = 1;                  /* We are running down below */
                    707:     if (shell_pid = vfork()) {
                    708:        if (shell_pid == -1) {
                    709:            perror("vfork");
                    710:            (void) close(serversock);
                    711:        } else {
                    712:            state = UNCONNECTED;
                    713:        }
                    714:     } else {                           /* New process */
                    715:        register int i;
                    716: 
                    717:        for (i = 3; i < 30; i++) {
                    718:            (void) close(i);
                    719:        }
                    720:        if (argc == 1) {                /* Just get a shell */
                    721:            char *cmdname;
                    722:            extern char *getenv();
                    723: 
                    724:            cmdname = getenv("SHELL");
                    725:            execlp(cmdname, cmdname, 0);
                    726:            perror("Exec'ing new shell...\n");
                    727:            exit(1);
                    728:        } else {
                    729:            execvp(argv[1], &argv[1]);
                    730:            perror("Exec'ing command.\n");
                    731:            exit(1);
                    732:        }
                    733:        /*NOTREACHED*/
                    734:     }
                    735:     return shell_active;               /* Go back to main loop */
                    736: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.