Annotation of 43BSDReno/contrib/isode-beta/others/quipu/uips/fred/pipe.c, revision 1.1.1.1

1.1       root        1: /* pipe.c - fred talks to dish */
                      2: 
                      3: #ifndef        lint
                      4: static char *rcsid = "$Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.6 90/07/27 08:45:26 mrose Exp $";
                      5: #endif
                      6: 
                      7: /* 
                      8:  * $Header: /f/osi/others/quipu/uips/fred/RCS/pipe.c,v 7.6 90/07/27 08:45:26 mrose Exp $
                      9:  *
                     10:  *
                     11:  * $Log:       pipe.c,v $
                     12:  * Revision 7.6  90/07/27  08:45:26  mrose
                     13:  * update
                     14:  * 
                     15:  * Revision 7.5  90/06/11  21:17:10  mrose
                     16:  * touch-up
                     17:  * 
                     18:  * Revision 7.4  90/06/11  10:55:32  mrose
                     19:  * UFN
                     20:  * 
                     21:  * Revision 7.3  90/01/16  20:43:41  mrose
                     22:  * last check-out
                     23:  * 
                     24:  * Revision 7.2  90/01/11  18:36:39  mrose
                     25:  * real-sync
                     26:  * 
                     27:  * Revision 7.1  89/12/13  20:01:51  mrose
                     28:  * errfp
                     29:  * 
                     30:  * Revision 7.0  89/11/23  22:09:03  mrose
                     31:  * Release 6.0
                     32:  * 
                     33:  */
                     34: 
                     35: /*
                     36:  *                               NOTICE
                     37:  *
                     38:  *    Acquisition, use, and distribution of this module and related
                     39:  *    materials are subject to the restrictions of a license agreement.
                     40:  *    Consult the Preface in the User's Manual for the full terms of
                     41:  *    this agreement.
                     42:  *
                     43:  */
                     44: 
                     45: 
                     46: #include <signal.h>
                     47: #include "fred.h"
                     48: #include "internet.h"
                     49: 
                     50: #include <sys/ioctl.h>
                     51: #ifndef        SYS5
                     52: #include <sys/file.h>
                     53: #else
                     54: #if    !defined(AIX) && !defined(HPUX)
                     55: #include <sys/fcntl.h>
                     56: #else
                     57: #include <fcntl.h>
                     58: #endif
                     59: #endif
                     60: #include <sys/stat.h>
                     61: #include "usr.dirent.h"
                     62: #ifdef BSD42
                     63: #include <sys/wait.h>
                     64: #endif
                     65: 
                     66: /*  */
                     67: 
                     68: int    didbind = 0;
                     69: int    dontpage = 0;
                     70: 
                     71: static int     dish_running = NOTOK;
                     72: 
                     73: static struct sockaddr_in sin;
                     74: 
                     75: /*    DISH */
                     76: 
                     77: int    dish (command, silent)
                     78: char   *command;
                     79: int    silent;
                     80: {
                     81:     int            cc,
                     82:            isarea,
                     83:            isuser,
                     84:            n,
                     85:            sd,
                     86:            status;
                     87:     char    buffer[BUFSIZ],
                     88:            where[BUFSIZ];
                     89:     register struct sockaddr_in *sock = &sin;
                     90:     FILE   *fp;
                     91: 
                     92:     if (watch) {
                     93:        fprintf (stderr, "%s\n", command);
                     94:        (void) fflush (stderr);
                     95:     }
                     96: 
                     97:     isarea = strncmp (command, "moveto -pwd", sizeof "moveto -pwd" - 1)
                     98:                ? 0 : 1;
                     99:     isuser = !isarea && strcmp (command, "squid -fred -user") == 0;
                    100: 
                    101:     if (dish_running != NOTOK && kill (dish_running, 0) == NOTOK)
                    102:        dish_running = NOTOK;
                    103: 
                    104:     if (dish_running == NOTOK) {
                    105:        int     vecp;
                    106:        char    dishname[BUFSIZ],
                    107:               *vec[10];
                    108:        static int very_first_time = 1;
                    109: 
                    110:        if (very_first_time) {
                    111:            (void) unsetenv ("DISHPROC");
                    112:            (void) unsetenv ("DISHPARENT");
                    113: 
                    114:            (void) strcpy (ufn_file, "/tmp/ufnrc.XXXXXX");
                    115:            (void) unlink (mktemp (ufn_file));
                    116:            (void) setenv ("UFNRC", ufn_file);
                    117: 
                    118:            very_first_time = 0;
                    119:        }
                    120: 
                    121:        if (get_dish_sock (&sin, getpid ()) == NOTOK)
                    122:            exit (1);
                    123: 
                    124:        (void) strcpy (dishname, _isodefile (isodebinpath, "dish"));
                    125: 
                    126: fork_again: ;
                    127:        switch (dish_running = vfork ()) {
                    128:            case NOTOK:
                    129:                adios ("fork", "unable to");
                    130:                /* NOT REACHED */
                    131: 
                    132:            case OK:
                    133:                if (ifd != NOTOK)
                    134:                    (void) close (ifd);
                    135:                if (ofd != NOTOK)
                    136:                    (void) close (ofd);
                    137:                vecp = 0;
                    138:                vec[vecp++] = "dish";
                    139:                vec[vecp++] = "-pipe";
                    140:                vec[vecp++] = "-fast";
                    141:                vec[vecp] = NULL;
                    142:                (void) execv (dishname, vec);
                    143:                fprintf (stderr, "unable to exec ");
                    144:                perror (dishname);
                    145:                _exit (1);
                    146: 
                    147:            default:
                    148:                for (;;) {
                    149:                    if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0))
                    150:                            == NOTOK)
                    151:                        adios ("client", "unable to start");
                    152:                    if (join_tcp_server (sd, sock) != NOTOK)
                    153:                        break;
                    154: 
                    155:                    (void) close_tcp_socket (sd);
                    156: 
                    157:                    sleep (5);
                    158: 
                    159:                    if (kill (dish_running, 0) == NOTOK)
                    160:                        goto fork_again;
                    161:                }
                    162:                didbind = 0;
                    163:                (void) signal (SIGPIPE, SIG_IGN);
                    164:                break;
                    165:        }
                    166:     }
                    167:     else {
                    168:        if ((sd = start_tcp_client ((struct sockaddr_in *) 0, 0)) == NOTOK)
                    169:            adios ("client", "unable to start");
                    170:        if (join_tcp_server (sd, sock) == NOTOK)
                    171:            adios ("server", "unable to join");
                    172:     }
                    173: 
                    174:     n = send (sd, command, cc = strlen (command), 0);
                    175:     if (debug)
                    176:        fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc);
                    177: 
                    178:     if (n != cc)
                    179:        if (n == NOTOK) {
                    180:            advise ("please retry", "write to DUA failed,");
                    181:            (void) f_quit (NULLVP);
                    182:            (void) close_tcp_socket (sd);
                    183:            return NOTOK;
                    184:        }
                    185:        else
                    186:            adios (NULLCP, "write to DUA truncated, sent %d of %d octets",
                    187:                   n, cc);
                    188: 
                    189:     status = OK;
                    190:     for (;;) {
                    191:        if ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) == NOTOK) {
                    192:            if (!interrupted)
                    193:                adios ("failed", "read from DUA");
                    194: 
                    195:            (void) kill (dish_running, SIGINT);
                    196:            interrupted = 0;
                    197:            continue;
                    198:        }
                    199: 
                    200:        buffer[cc] = NULL;
                    201:        if (debug)
                    202:            fprintf (stderr, "read %d octets from DUA: 0x%x\n", cc, buffer[0]);
                    203:        if (cc == OK) {
                    204:            if (kill (dish_running, 0) == NOTOK)
                    205:                advise (NULLCP, "lost DUA");
                    206: 
                    207:            break;
                    208:        }
                    209: 
                    210:        switch (buffer[0]) {
                    211:            case '2':
                    212:                if ((fp = errfp) == NULL)
                    213:                    fp = stdfp != stdout ? stdfp : stderr;
                    214:                status = NOTOK;
                    215:                
                    216: copy_out: ;
                    217:                if (cc > 1 && !silent)
                    218:                    paginate (fp, buffer + 1, cc - 1);
                    219:                            
                    220:                while ((cc = recv (sd, buffer, sizeof buffer - 1, 0)) > OK)
                    221:                    if (!silent)
                    222:                        paginate (fp, buffer, cc);
                    223: 
                    224:                if (!silent)
                    225:                    paginate (fp, NULLCP, 0);
                    226:                break;
                    227: 
                    228:            case '1':
                    229:            case '3':
                    230:                if (isarea || isuser) {
                    231:                    char   *cp,
                    232:                          **vp;
                    233: 
                    234:                    if (cp = index (buffer + 1, '\n'))
                    235:                        *cp = NULL;
                    236: #ifdef notdef
                    237:                    if (buffer[1] == NULL)
                    238:                        break;
                    239: #endif
                    240:                    buffer[0] = '@';
                    241:                    vp = isarea ? &myarea : &mydn;
                    242: 
                    243:                    if (*vp)
                    244:                        free (*vp);
                    245:                    *vp = strdup (buffer);
                    246:                }
                    247:                fp = stdfp;
                    248:                goto copy_out;
                    249: 
                    250:            case 'e':
                    251:                if (watch) {
                    252:                    fprintf (stderr, "%s\n", buffer + 1);
                    253:                    (void) fflush (stderr);
                    254:                }
                    255:                if (system (buffer + 1))
                    256:                    (void) strcpy (where, "e");
                    257:                else
                    258:                    (void) getcwd (where, sizeof where);
                    259:                goto stuff_it;
                    260: 
                    261:            case 'y':
                    262:                if (network)
                    263:                    (void) strcpy (where, "n");
                    264:                else {
                    265:                    fprintf (stderr, "%s", buffer + 1);
                    266:                    (void) fflush (stderr);
                    267:                    (void) fgets (where, sizeof where, stdin);
                    268:                }
                    269:                goto stuff_it;
                    270: 
                    271:            case 'p':
                    272:                (void) sprintf (where, "Enter password for \"%s\": ",
                    273:                                buffer + 1);
                    274:                (void) strcpy (where, getpassword (where));
                    275: 
                    276: stuff_it: ;
                    277:                n = send (sd, where, cc = strlen (where), 0);
                    278:                if (debug)
                    279:                    fprintf (stderr, "wrote %d of %d octets to DUA\n", n, cc);
                    280: 
                    281:                if (n != cc)
                    282:                    if (n == NOTOK) {
                    283:                        advise ("please retry", "write to DUA failed,");
                    284:                        (void) f_quit (NULLVP);
                    285:                        (void) close_tcp_socket (sd);
                    286:                        return NOTOK;
                    287:                    }
                    288:                    else
                    289:                        adios (NULLCP,
                    290:                               "write to DUA truncated, sent %d of %d octets",
                    291:                               n, cc);
                    292:                continue;
                    293: 
                    294:            default:
                    295:                advise (NULLCP, "unexpected opcode 0x%x -- contact a camayoc",
                    296:                        buffer[0]);
                    297:                break;
                    298:        }
                    299:        break;
                    300:     }
                    301: 
                    302:     (void) close_tcp_socket (sd);
                    303: 
                    304:     return status;
                    305: }
                    306: 
                    307: /*  */
                    308: 
                    309: paginate (fp, buffer, cc)
                    310: FILE   *fp;
                    311: char   *buffer;
                    312: int    cc;
                    313: {
                    314:     static int first_time = 1;
                    315:     static int doing_pager = 0;
                    316:     static int pid = NOTOK;
                    317:     static int sd = NOTOK;
                    318:     static SFP istat, qstat;
                    319: 
                    320:     if (cc == 0) {
                    321: #ifndef        BSD42
                    322:        int     status;
                    323: #else
                    324:        union wait status;
                    325: #endif
                    326:        int     child;
                    327: 
                    328:        first_time = 1;
                    329:        (void) fflush (fp);
                    330:        if (!doing_pager)
                    331:            return;
                    332: 
                    333:        doing_pager = 0;
                    334: 
                    335:        if (dup2 (sd, fileno (fp)) == NOTOK)
                    336:            adios ("standard output", "unable to dup2");
                    337: 
                    338:        clearerr (fp);
                    339:        (void) close (sd);
                    340: 
                    341:        while ((child = wait (&status)) != NOTOK && pid != child)
                    342:            continue;
                    343: 
                    344:        (void) signal (SIGINT, istat);
                    345:        (void) signal (SIGQUIT, qstat);
                    346: 
                    347:        return;
                    348:     }
                    349: 
                    350:     if (first_time) {
                    351:        int     pd[2];
                    352: 
                    353:        first_time = 0;
                    354: 
                    355:        if (dontpage || network || *pager == NULL || !isatty (fileno (fp)))
                    356:            goto no_pager;
                    357: 
                    358:        (void) fflush (fp);
                    359: 
                    360:        foreground ();
                    361: 
                    362:        if ((sd = dup (fileno (fp))) == NOTOK) {
                    363:            advise ("dup", "unable to");
                    364:            goto no_pager;
                    365:        }
                    366: 
                    367:        if (pipe (pd) == NOTOK) {
                    368:            advise ("pipe", "unable to");
                    369:            goto no_pager;
                    370:        }
                    371:        switch (pid = fork ()) {
                    372:            case NOTOK:
                    373:                advise ("fork", "unable to");
                    374:                (void) close (pd[0]);
                    375:                (void) close (pd[1]);
                    376:                goto no_pager;
                    377: 
                    378:            case OK:
                    379:                (void) signal (SIGINT, SIG_DFL);
                    380:                (void) signal (SIGQUIT, SIG_DFL);
                    381: 
                    382:                (void) close (pd[1]);
                    383:                if (pd[0] != fileno (stdin)) {
                    384:                    (void) dup2 (pd[0], fileno (stdin));
                    385:                    (void) close (pd[0]);
                    386:                }
                    387:                if (readonly)
                    388:                    mypager (stdin);
                    389:                else {
                    390:                    execlp (pager, pager, NULLCP);
                    391:                    fprintf (stderr, "unable to exec ");
                    392:                    perror (pager);
                    393:                }
                    394:                _exit (-1);
                    395: 
                    396:            default:
                    397:                (void) close (pd[0]);
                    398:                if (pd[1] != fileno (fp)) {
                    399:                    (void) dup2 (pd[1], fileno (fp));
                    400:                    (void) close (pd[1]);
                    401:                }
                    402:                break;
                    403:        }
                    404: 
                    405:        istat = signal (SIGINT, SIG_IGN);
                    406:        qstat = signal (SIGQUIT, SIG_IGN);
                    407: 
                    408:        doing_pager = 1;
                    409:     }
                    410: 
                    411: no_pager: ;
                    412:     if (network && !mail) {
                    413:        register char *cp,
                    414:                      *dp;
                    415: 
                    416:        for (dp = (cp = buffer) + cc; cp < dp; cp++) {
                    417:            if (*cp == '\n')
                    418:                (void) fputc ('\r', fp);
                    419:            (void) fputc (*cp, fp);
                    420:        }
                    421:     }
                    422:     else
                    423:        (void) fwrite (buffer, sizeof buffer[0], cc, fp);
                    424: }
                    425: 
                    426: /*  */
                    427: 
                    428: /* if you start a fred command and then background fred, if your pager is less,
                    429:    then for some reason, less gets the terminal modes/process groups messed up.
                    430: 
                    431:    this code pretty much ensures that fred is running in the foreground when
                    432:    it forks less.  there is still a critical window, but it is very small...
                    433:  */
                    434: 
                    435: static  foreground () {
                    436: #ifdef TIOCGPGRP
                    437:     int     pgrp,
                    438:             tpgrp;
                    439:     SFP            tstat;
                    440: 
                    441:     if ((pgrp = getpgrp (0)) == NOTOK)
                    442:        return;
                    443: 
                    444:     tstat = signal (SIGTTIN, SIG_DFL);
                    445:     for (;;) {
                    446:        if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK)
                    447:            break;
                    448:        if (pgrp == tpgrp)
                    449:            break;
                    450: 
                    451:        (void) kill (0, SIGTTIN);
                    452:     }
                    453:     (void) signal (SIGTTIN, tstat);
                    454: #endif
                    455: }
                    456: 
                    457: /*  */
                    458: 
                    459: static int     cols;
                    460: static int     rows;
                    461: static int     length = 0;
                    462: static int     width = 0;
                    463: 
                    464: 
                    465: static mypager (fp)
                    466: FILE   *fp;
                    467: {
                    468:     register char *bp;
                    469:     char    buffer[BUFSIZ];
                    470: #ifdef TIOCGWINSZ
                    471:     struct winsize    ws;
                    472: #endif
                    473: 
                    474: #ifdef TIOCGWINSZ
                    475:     if (ioctl (fileno (stdout), TIOCGWINSZ, (char *) &ws) != NOTOK)
                    476:        length = ws.ws_row, width = ws.ws_col;
                    477: #endif
                    478:     if (--length <= 0)
                    479:        length = 23;
                    480:     if (--width <= 0)
                    481:        width = 79;
                    482: 
                    483:     rows = cols = 0;
                    484: 
                    485:     while (fgets (buffer, sizeof buffer, fp))
                    486:        for (bp = buffer; *bp; bp++)
                    487:            pagchar (*bp);
                    488: 
                    489:     (void) fflush (stdout);
                    490: }
                    491: 
                    492: 
                    493: static pagchar (ch)
                    494: char   ch;
                    495: {
                    496:     char    buffer[BUFSIZ];
                    497: 
                    498:     switch (ch) {
                    499:         case '\n':
                    500:            cols = 0;
                    501:            if (++rows < length)
                    502:                break;
                    503:            (void) putc (0x07, stdout);
                    504:            (void) fflush (stdout);
                    505:            buffer[0] = NULL;
                    506:            (void) read (fileno (stdout), buffer, sizeof buffer);
                    507:            if (buffer[0] == '\n')
                    508:                rows = 0;
                    509:            else {
                    510:                (void) putc ('\n', stdout);
                    511:                rows = length / 3;
                    512:            }
                    513:            return;
                    514: 
                    515:        case '\t':
                    516:            cols |= 07;
                    517:            cols++;
                    518:            break;
                    519: 
                    520:        case '\b':
                    521:            cols--;
                    522:            break;
                    523: 
                    524:        case '\r':
                    525:            cols = 0;
                    526:            break;
                    527: 
                    528:        default:
                    529:            if (ch >= ' ')
                    530:                cols++;
                    531:            break;
                    532:        }
                    533: 
                    534:     if (cols >= width) {
                    535:        pagchar ('\n');
                    536:        pagchar (ch);
                    537:     }
                    538:     else
                    539:        (void) putc (ch, stdout);
                    540: }
                    541: 
                    542: /*    BIND */
                    543: 
                    544: /* ARGSUSED */
                    545: 
                    546: int    f_bind (vec)
                    547: char  **vec;
                    548: {
                    549:     if (didbind) {
                    550:        didbind = 0;
                    551:        return OK;
                    552:     }
                    553: 
                    554: #ifdef notdef
                    555:     if (dish_running == NOTOK || kill (dish_running, 0) == NOTOK)
                    556:        return dish ("bind", 0);
                    557: 
                    558:     return OK;
                    559: #else
                    560:     return dish ("bind", 0);
                    561: #endif
                    562: }
                    563: 
                    564: /* ARGSUSED */
                    565: 
                    566: /*    QUIT */
                    567: 
                    568: int    f_quit (vec)
                    569: char  **vec;
                    570: {
                    571:     if (vec && *++vec != NULL && strcmp (*vec, "-help") == 0) {
                    572:        fprintf (stdfp, "quit\n");
                    573:        fprintf (stdfp, "    terminate fred\n");
                    574: 
                    575:        return OK;
                    576:     }
                    577: 
                    578:     if (dish_running != NOTOK) {
                    579:        (void) kill (dish_running, SIGHUP);
                    580: 
                    581:        dish_running = NOTOK;
                    582:     }
                    583:     
                    584:     if (ufn_file[0])
                    585:        (void) unlink (ufn_file);
                    586: 
                    587:     return DONE;
                    588: }

unix.superglobalmegacorp.com

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