Annotation of 43BSDReno/contrib/mh/uip/vmh.c, revision 1.1.1.1

1.1       root        1: /* vmh.c - visual front-end to mh */
                      2: 
                      3: /* TODO:
                      4:        Pass signals to client during execution
                      5: 
                      6:        Get stand-alone SO/SE/CE to work under #ifdef SYS5
                      7: 
                      8:        Figure out a way for the user to say how big the Scan/Display
                      9:        windows should be.
                     10: 
                     11:        If curses ever gets fixed, then XYZ code can be removed
                     12:  */
                     13: 
                     14: #include <curses.h>
                     15: #undef OK                      /* tricky */
                     16: #include "../h/mh.h"
                     17: #include "../h/vmhsbr.h"
                     18: #include <ctype.h>
                     19: #include <errno.h>
                     20: #include <setjmp.h>
                     21: #include <signal.h>
                     22: #ifndef        sigmask
                     23: #define        sigmask(s)      (1 << ((s) - 1))
                     24: #endif not sigmask
                     25: #ifndef        BSD42
                     26: struct iovec {
                     27:     char   *iov_base;
                     28:     int     iov_len;
                     29: };
                     30: #else  BSD42
                     31: #include <sys/types.h>
                     32: #include <sys/uio.h>
                     33: #endif BSD42
                     34: 
                     35: #define        ALARM   ((unsigned int) 10)
                     36: #define        PAUSE   ((unsigned int) 2)
                     37: 
                     38: #define        abs(a)          ((a) > 0 ? (a) : -(a))
                     39: #define        SMALLMOVE       1
                     40: #define        LARGEMOVE       10
                     41: 
                     42: 
                     43: #define        XYZ                     /* XXX */
                     44: 
                     45: /*  */
                     46: 
                     47: static struct swit switches[] = {
                     48: #define        PRMPTSW 0
                     49:     "prompt string", 6,
                     50: 
                     51: #define        PROGSW  1
                     52:     "vmhproc program", 7,
                     53: #define        NPROGSW 2
                     54:     "novmhproc", 9,
                     55: 
                     56: #define        HELPSW  3
                     57:     "help", 4,
                     58: 
                     59:     NULL, NULL
                     60: };
                     61: 
                     62: /*  */
                     63:                                        /* PEERS */
                     64: static int  PEERpid = NOTOK;
                     65: 
                     66: static  jmp_buf PEERctx;
                     67: 
                     68: 
                     69:                                        /* WINDOWS */
                     70: static char *myprompt = "(%s) ";
                     71: 
                     72: static  WINDOW *Scan;
                     73: static  WINDOW *Status;
                     74: static  WINDOW *Display;
                     75: static  WINDOW *Command;
                     76: 
                     77: #define        NWIN    3
                     78: static int numwins;
                     79: WINDOW *windows[NWIN + 1];
                     80: 
                     81: 
                     82:                                        /* LINES */
                     83: 
                     84: struct line {
                     85:     int     l_no;
                     86:     char   *l_buf;
                     87:     struct line *l_prev;
                     88:     struct line *l_next;
                     89: };
                     90: 
                     91: static struct line *lhead = NULL;
                     92: static struct line *ltop = NULL;
                     93: static struct line *ltail = NULL;
                     94: 
                     95: static int did_less = 0;
                     96: static int smallmove = SMALLMOVE;
                     97: static int largemove = LARGEMOVE;
                     98: 
                     99: 
                    100:                                        /* TTYS */
                    101: 
                    102: static int  tty_ready = NOTOK;
                    103: 
                    104: static int  intrc;
                    105: #ifndef        SYS5
                    106: #define        ERASE   sg.sg_erase
                    107: #define        KILL    sg.sg_kill
                    108: static struct sgttyb    sg;
                    109: 
                    110: #define        EOFC    tc.t_eofc
                    111: #define        INTR    tc.t_intrc
                    112: static struct tchars    tc;
                    113: #else  SYS5
                    114: #define        ERASE   sg.c_cc[VERASE]
                    115: #define        KILL    sg.c_cc[VKILL]
                    116: #define        EOFC    sg.c_cc[VEOF]
                    117: #define        INTR    sg.c_cc[VINTR]
                    118: static struct termio    sg;
                    119: #endif SYS5
                    120: 
                    121: #ifndef        TIOCGLTC
                    122: #define        WERASC  ('W' & 037)
                    123: #else  TIOCGLTC
                    124: #define        WERASC  ltc.t_werasc
                    125: static struct ltchars ltc;
                    126: #endif TIOCGLTC
                    127: 
                    128: 
                    129: #ifndef        SYS5
                    130: int    _putchar ();
                    131: #endif not SYS5
                    132: char   *tgoto ();
                    133: 
                    134: extern int errno;
                    135: extern int sys_nerr;
                    136: extern char *sys_errlist[];
                    137: 
                    138: static int PEERinit(), pINI(), pLOOP(), pTTY(), pWIN(), pWINaux(), pFIN(),
                    139:     WINinit(), WINgetstr(), WINwritev(), WINless(), WINputc(), ladvance(),
                    140:     lretreat(), lgo(), TTYinit(), ALRMser(), PIPEser(), SIGser(), TSTPser();
                    141: static void vmh(), lreset(), linsert(), TTYon(), TTYoff(), foreground(),
                    142:     sideground(), adorn();
                    143: 
                    144: 
                    145: /*  */
                    146: 
                    147: /* ARGSUSED */
                    148: 
                    149: main(argc, argv)
                    150:        int argc;
                    151:        char *argv[];
                    152: {
                    153:     int     vecp = 1,
                    154:            nprog = 0;
                    155:     char   *cp,
                    156:             buffer[BUFSIZ],
                    157:           **ap,
                    158:           **argp,
                    159:            *arguments[MAXARGS],
                    160:            *vec[MAXARGS];
                    161: 
                    162:     invo_name = r1bindex (argv[0], '/');
                    163:     if ((cp = m_find (invo_name)) != NULL) {
                    164:        ap = brkstring (cp = getcpy (cp), " ", "\n");
                    165:        ap = copyip (ap, arguments);
                    166:     }
                    167:     else
                    168:        ap = arguments;
                    169:     (void) copyip (argv + 1, ap);
                    170:     argp = arguments;
                    171: 
                    172: /*  */
                    173: 
                    174:     while (cp = *argp++)
                    175:        if (*cp == '-')
                    176:            switch (smatch (++cp, switches)) {
                    177:                case AMBIGSW:
                    178:                    ambigsw (cp, switches);
                    179:                    done (1);
                    180:                case UNKWNSW:
                    181:                    vec[vecp++] = --cp;
                    182:                    continue;
                    183:                case HELPSW:
                    184:                    (void) sprintf (buffer, "%s [switches for vmhproc]",
                    185:                            invo_name);
                    186:                    help (buffer, switches);
                    187:                    done (1);
                    188: 
                    189:                case PRMPTSW:
                    190:                    if (!(myprompt = *argp++) || *myprompt == '-')
                    191:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    192:                    continue;
                    193: 
                    194:                case PROGSW:
                    195:                    if (!(vmhproc = *argp++) || *vmhproc == '-')
                    196:                        adios (NULLCP, "missing argument to %s", argp[-2]);
                    197:                    continue;
                    198:                case NPROGSW:
                    199:                    nprog++;
                    200:                    continue;
                    201:            }
                    202:        else
                    203:            vec[vecp++] = cp;
                    204: 
                    205: /*  */
                    206: 
                    207:     if (TTYinit (nprog) == NOTOK || WINinit (nprog) == NOTOK) {
                    208:        vec[vecp] = NULL;
                    209: 
                    210:        vec[0] = r1bindex (vmhproc, '/');
                    211:        execvp (vmhproc, vec);
                    212:        adios (vmhproc, "unable to exec");
                    213:     }
                    214:     TTYoff ();
                    215:     (void) PEERinit (vecp, vec);
                    216:     TTYon ();
                    217: 
                    218:     vmh ();
                    219: 
                    220:     done (0);
                    221: }
                    222: 
                    223: /*  */
                    224: 
                    225: static void
                    226: vmh()
                    227: {
                    228:     char    buffer[BUFSIZ];
                    229: 
                    230:     for (;;) {
                    231:        (void) pLOOP (RC_QRY, NULLCP);
                    232: 
                    233:        wmove (Command, 0, 0);
                    234:        wprintw (Command, myprompt, invo_name);
                    235:        wclrtoeol (Command);
                    236:        wrefresh (Command);
                    237: 
                    238:        switch (WINgetstr (Command, buffer)) {
                    239:            case NOTOK:
                    240:                break;
                    241: 
                    242:            case OK:
                    243:                done (0);       /* NOTREACHED */
                    244: 
                    245:            default:
                    246:                if (*buffer)
                    247:                    (void) pLOOP (RC_CMD, buffer);
                    248:                break;
                    249:        }
                    250:     }
                    251: }
                    252: 
                    253: /*    PEERS */
                    254: 
                    255: static int
                    256: PEERinit(vecp, vec)
                    257:        int vecp;
                    258:        char *vec[];
                    259: {
                    260:     int            pfd0[2],
                    261:             pfd1[2];
                    262:     char    buf1[BUFSIZ],
                    263:             buf2[BUFSIZ];
                    264: 
                    265:     if (pipe (pfd0) == NOTOK || pipe (pfd1) == NOTOK)
                    266:        adios ("pipe", "unable to");
                    267:     switch (PEERpid = vfork ()) {
                    268:        case NOTOK:
                    269:            adios ("vfork", "unable to");/* NOTREACHED */
                    270: 
                    271:        case OK:
                    272:            (void) close (pfd0[0]);
                    273:            (void) close (pfd1[1]);
                    274: 
                    275:            vec[vecp++] = "-vmhread";
                    276:            (void) sprintf (buf1, "%d", pfd1[0]);
                    277:            vec[vecp++] = buf1;
                    278:            vec[vecp++] = "-vmhwrite";
                    279:            (void) sprintf (buf2, "%d", pfd0[1]);
                    280:            vec[vecp++] = buf2;
                    281:            vec[vecp] = NULL;
                    282: 
                    283:            (void) signal (SIGINT, SIG_DFL);
                    284:            (void) signal (SIGQUIT, SIG_DFL);
                    285: 
                    286:            vec[0] = r1bindex (vmhproc, '/');
                    287:            execvp (vmhproc, vec);
                    288:            perror (vmhproc);
                    289:            _exit (-1);         /* NOTREACHED */
                    290: 
                    291:        default:
                    292:            (void) close (pfd0[1]);
                    293:            (void) close (pfd1[0]);
                    294: 
                    295:            (void) rcinit (pfd0[0], pfd1[1]);
                    296:            return pINI ();
                    297:     }
                    298: }
                    299: 
                    300: /*  */
                    301: 
                    302: static int
                    303: pINI()
                    304: {
                    305:     register char  *bp;
                    306:     char    buffer[BUFSIZ];
                    307:     struct record   rcs;
                    308:     register struct record *rc = &rcs;
                    309:     register    WINDOW **w;
                    310: 
                    311:     initrc (rc);
                    312: 
                    313:     bp = buffer;
                    314:     (void) sprintf (bp, "%d %d", RC_VRSN, numwins);
                    315:     bp += strlen (bp);
                    316:     for (w = windows; *w; w++) {
                    317:        (void) sprintf (bp, " %d", (*w) -> _maxy);
                    318:        bp += strlen (bp);
                    319:     }
                    320: 
                    321:     switch (str2rc (RC_INI, buffer, rc)) {
                    322:        case RC_ACK:
                    323:            return OK;
                    324: 
                    325:        case RC_ERR:
                    326:            if (rc -> rc_len)
                    327:                adios (NULLCP, "%s", rc -> rc_data);
                    328:            else
                    329:                adios (NULLCP, "pINI peer error");
                    330: 
                    331:        case RC_XXX:
                    332:            adios (NULLCP, "%s", rc -> rc_data);
                    333: 
                    334:        default:
                    335:            adios (NULLCP, "pINI protocol screw-up");
                    336:     }
                    337: /* NOTREACHED */
                    338: }
                    339: 
                    340: /*  */
                    341: 
                    342: static int
                    343: pLOOP(code, str)
                    344:        char code, *str;
                    345: {
                    346:     int            i;
                    347:     struct record   rcs;
                    348:     register struct record *rc = &rcs;
                    349: 
                    350:     initrc (rc);
                    351: 
                    352:     (void) str2peer (code, str);
                    353:     for (;;)
                    354:        switch (peer2rc (rc)) {
                    355:            case RC_TTY:
                    356:                if (pTTY (rc) == NOTOK)
                    357:                    return NOTOK;
                    358:                break;
                    359: 
                    360:            case RC_WIN:
                    361:                if (sscanf (rc -> rc_data, "%d", &i) != 1
                    362:                        || i <= 0
                    363:                        || i > numwins) {
                    364:                    (void) fmt2peer (RC_ERR, "no such window \"%s\"",
                    365:                                rc -> rc_data);
                    366:                    return NOTOK;
                    367:                }
                    368:                if (pWIN (windows[i - 1]) == NOTOK)
                    369:                    return NOTOK;
                    370:                break;
                    371: 
                    372:            case RC_EOF:
                    373:                return OK;
                    374: 
                    375:            case RC_ERR:
                    376:                if (rc -> rc_len)
                    377:                    adorn (NULLCP, "%s", rc -> rc_data);
                    378:                else
                    379:                    adorn (NULLCP, "pLOOP(%s) peer error",
                    380:                            code == RC_QRY ? "QRY" : "CMD");
                    381:                return NOTOK;
                    382: 
                    383:            case RC_FIN:
                    384:                if (rc -> rc_len)
                    385:                    adorn (NULLCP, "%s", rc -> rc_data);
                    386:                (void) rcdone ();
                    387:                i = pidwait (PEERpid, OK);
                    388:                PEERpid = NOTOK;
                    389:                done (i);
                    390: 
                    391:            case RC_XXX:
                    392:                adios (NULLCP, "%s", rc -> rc_data);
                    393: 
                    394:            default:
                    395:                adios (NULLCP, "pLOOP(%s) protocol screw-up",
                    396:                        code == RC_QRY ? "QRY" : "CMD");
                    397:        }
                    398: }
                    399: 
                    400: /*  */
                    401: 
                    402: static int
                    403: pTTY(r)
                    404:        register struct record *r;
                    405: {
                    406:     SIGDECL (*hstat)(), (*istat)(), (*qstat)(), (*tstat)();
                    407:     struct record   rcs;
                    408:     register struct record *rc = &rcs;
                    409: 
                    410:     initrc (rc);
                    411: 
                    412:     TTYoff ();
                    413: 
                    414:     hstat = signal (SIGHUP, SIG_IGN);
                    415:     istat = signal (SIGINT, SIG_IGN);
                    416:     qstat = signal (SIGQUIT, SIG_IGN);
                    417:     tstat = signal (SIGTERM, SIG_IGN);
                    418: 
                    419:     (void) rc2rc (RC_ACK, 0, NULLCP, rc);
                    420: 
                    421:     (void) signal (SIGHUP, hstat);
                    422:     (void) signal (SIGINT, istat);
                    423:     (void) signal (SIGQUIT, qstat);
                    424:     (void) signal (SIGTERM, tstat);
                    425: 
                    426:     TTYon ();
                    427: 
                    428:     if (r -> rc_len && strcmp (r -> rc_data, "FAST") == 0)
                    429:        goto no_refresh;
                    430: 
                    431: #ifdef SIGTSTP
                    432:     (void) signal (SIGTSTP, SIG_IGN);
                    433: #endif SIGTSTP
                    434: #ifndef        SYS5
                    435:     if (SO)
                    436:        tputs (SO, 0, _putchar);
                    437: #endif not SYS5
                    438:     fprintf (stdout, "Type any key to continue... ");
                    439:     (void) fflush (stdout);
                    440: #ifndef        SYS5
                    441:     if (SE)
                    442:        tputs (SE, 0, _putchar);
                    443: #endif not SYS5
                    444:     (void) getc (stdin);
                    445: #ifdef SIGTSTP
                    446:     (void) signal (SIGTSTP, TSTPser);
                    447: #endif SIGTSTP
                    448: 
                    449:     wrefresh (curscr);
                    450: 
                    451: no_refresh: ;
                    452:     switch (rc -> rc_type) {
                    453:        case RC_EOF:
                    454:            (void) rc2peer (RC_ACK, 0, NULLCP);
                    455:            return OK;
                    456: 
                    457:        case RC_ERR:
                    458:            if (rc -> rc_len)
                    459:                adorn (NULLCP, "%s", rc -> rc_data);
                    460:            else
                    461:                adorn (NULLCP, "pTTY peer error");
                    462:            return NOTOK;
                    463: 
                    464:        case RC_XXX:
                    465:            adios (NULLCP, "%s", rc -> rc_data);
                    466: 
                    467:        default:
                    468:            adios (NULLCP, "pTTY protocol screw-up");
                    469:     }
                    470: /* NOTREACHED */
                    471: }
                    472: 
                    473: /*  */
                    474: 
                    475: static int
                    476: pWIN(w)
                    477:        register WINDOW *w;
                    478: {
                    479:     int     i;
                    480: 
                    481:     did_less = 0;
                    482:     if ((i = pWINaux (w)) == OK && did_less)
                    483:        (void) WINless (w, 1);
                    484: 
                    485:     lreset ();
                    486: 
                    487:     return i;
                    488: }
                    489: 
                    490: /*  */
                    491: 
                    492: static int
                    493: pWINaux(w)
                    494:        register WINDOW *w;
                    495: {
                    496:     register int    n;
                    497:     int            eol;
                    498:     register char   c,
                    499:                    *bp;
                    500:     struct record   rcs;
                    501:     register struct record *rc = &rcs;
                    502: 
                    503:     initrc (rc);
                    504: 
                    505:     werase (w);
                    506:     wmove (w, 0, 0);
                    507: #ifdef XYZ
                    508:     if (w == Status)
                    509:        wstandout (w);
                    510: #endif XYZ
                    511: 
                    512:     for (eol = 0;;)
                    513:        switch (rc2rc (RC_ACK, 0, NULLCP, rc)) {
                    514:            case RC_DATA:
                    515:                if (eol && WINputc (w, '\n') == ERR && WINless (w, 0))
                    516:                    goto flush;
                    517:                for (bp = rc -> rc_data, n = rc -> rc_len; n-- > 0; ) {
                    518:                    if ((c = *bp++) == '\n')
                    519:                        linsert (w);
                    520:                    if (WINputc (w, c) == ERR)
                    521:                        if (n == 0 && c == '\n')
                    522:                            eol++;
                    523:                        else
                    524:                            if (WINless (w, 0)) {
                    525: flush: ;
                    526:                                (void) fmt2peer (RC_ERR, "flush window");
                    527: #ifdef XYZ                     /* should NEVER happen... */
                    528:                                if (w == Status)
                    529:                                    wstandend (w);
                    530: #endif XYZ
                    531:                                wrefresh (w);
                    532:                                return NOTOK;
                    533:                            }
                    534:                }
                    535:                break;
                    536: 
                    537:            case RC_EOF:
                    538:                (void) rc2peer (RC_ACK, 0, NULLCP);
                    539: #ifdef XYZ
                    540:                if (w == Status)
                    541:                    wstandend (w);
                    542: #endif XYZ
                    543:                wrefresh (w);
                    544:                return OK;
                    545: 
                    546:            case RC_ERR:
                    547:                if (rc -> rc_len)
                    548:                    adorn (NULLCP, "%s", rc -> rc_data);
                    549:                else
                    550:                    adorn (NULLCP, "pWIN peer error");
                    551:                return NOTOK;
                    552: 
                    553:            case RC_XXX:
                    554:                adios (NULLCP, "%s", rc -> rc_data);
                    555: 
                    556:            default:
                    557:                adios (NULLCP, "pWIN protocol screw-up");
                    558:        }
                    559: /* NOTREACHED */
                    560: }
                    561: 
                    562: /*  */
                    563: 
                    564: static int
                    565: pFIN()
                    566: {
                    567:     int     status;
                    568: 
                    569:     if (PEERpid <= OK)
                    570:        return OK;
                    571: 
                    572:     (void) rc2peer (RC_FIN, 0, NULLCP);
                    573:     (void) rcdone ();
                    574: 
                    575:     switch (setjmp (PEERctx)) {
                    576:        case OK:
                    577:            (void) signal (SIGALRM, ALRMser);
                    578:            (void) alarm (ALARM);
                    579: 
                    580:            status = pidwait (PEERpid, OK);
                    581: 
                    582:            (void) alarm (0);
                    583:            break;
                    584: 
                    585:        default:
                    586:            (void) kill (PEERpid, SIGKILL);
                    587:            status = NOTOK;
                    588:            break;
                    589:     }
                    590:     PEERpid = NOTOK;
                    591: 
                    592:     return status;
                    593: }
                    594: 
                    595: /*    WINDOWS */
                    596: 
                    597: static int
                    598: WINinit(nprog)
                    599: {
                    600:     register int    lines,
                    601:                     top,
                    602:                     bottom;
                    603: 
                    604:     foreground ();
                    605:     if (initscr () == ERR)
                    606:        if (nprog)
                    607:            return NOTOK;
                    608:        else
                    609:            adios (NULLCP, "could not initialize terminal");
                    610: #ifdef SIGTSTP
                    611:     (void) signal (SIGTSTP, SIG_DFL);
                    612: #endif SIGTSTP
                    613:     sideground ();
                    614: 
                    615:     if (CM == NULL)
                    616:        if (nprog)
                    617:            return NOTOK;
                    618:        else
                    619:            adios (NULLCP,
                    620:                    "sorry, your terminal isn't powerful enough to run %s",
                    621:                    invo_name);
                    622: 
                    623: #ifndef        SYS5
                    624:     if (tgetflag ("xt") || tgetnum ("sg") > 0)
                    625:        SO = SE = US = UE = NULL;
                    626: #endif not SYS5
                    627: 
                    628:     if ((lines = LINES - 1) < 11)
                    629:        adios (NULLCP, "screen too small");
                    630:     if ((top = lines / 3 + 1) > LINES / 4 + 2)
                    631:        top--;
                    632:     bottom = lines - top - 2;
                    633: 
                    634:     numwins = 0;
                    635:     Scan = windows[numwins++] = newwin (top, COLS, 0, 0);
                    636:     Status = windows[numwins++] = newwin (1, COLS, top, 0);
                    637: #ifndef        XYZ
                    638:     wstandout (Status);
                    639: #endif XYZ
                    640:     Display = windows[numwins++] = newwin (bottom, COLS, top + 1, 0);
                    641:     Command = newwin (1, COLS - 1, top + 1 + bottom, 0);
                    642:     windows[numwins] = NULL;
                    643: 
                    644:     largemove = Display -> _maxy / 2 + 2;
                    645:     return OK;
                    646: }
                    647: 
                    648: /*  */
                    649: 
                    650: static int
                    651: WINgetstr(w, buffer)
                    652:        register WINDOW *w;
                    653:        char *buffer;
                    654: {
                    655:     register int    c;
                    656:     register char  *bp;
                    657: 
                    658:     bp = buffer;
                    659:     *bp = NULL;
                    660: 
                    661:     for (;;) {
                    662:        switch (c = toascii (wgetch (w))) {
                    663:            case ERR:
                    664:                adios (NULLCP, "wgetch lost");
                    665: 
                    666:            case '\f':
                    667:                wrefresh (curscr);
                    668:                break;
                    669: 
                    670:            case '\r':
                    671:            case '\n':
                    672:                *bp = NULL;
                    673:                if (bp > buffer) {
                    674:                    leaveok (curscr, FALSE);
                    675:                    wmove (w, 0, w -> _curx - (bp - buffer));
                    676:                    wrefresh (w);
                    677:                    leaveok (curscr, TRUE);
                    678:                }
                    679:                return DONE;
                    680: 
                    681:            default:
                    682:                if (c == intrc) {
                    683:                    wprintw (w, " ");
                    684:                    wstandout (w);
                    685:                    wprintw (w, "Interrupt");
                    686:                    wstandend (w);
                    687:                    wrefresh (w);
                    688:                    *buffer = NULL;
                    689:                    return NOTOK;
                    690:                }
                    691:                if (c == EOFC) {
                    692:                    if (bp <= buffer)
                    693:                        return OK;
                    694:                    break;
                    695:                }
                    696:                if (c == ERASE) {
                    697:                    if (bp <= buffer)
                    698:                        continue;
                    699:                    bp--, w -> _curx--;
                    700:                    wclrtoeol (w);
                    701:                    break;
                    702:                }
                    703:                if (c == KILL) {
                    704:                    if (bp <= buffer)
                    705:                        continue;
                    706:                    w -> _curx -= bp - buffer;
                    707:                    bp = buffer;
                    708:                    wclrtoeol (w);
                    709:                    break;
                    710:                }
                    711:                if (c == WERASC) {
                    712:                    if (bp <= buffer)
                    713:                        continue;
                    714:                    do {
                    715:                        bp--, w -> _curx--;
                    716:                    } while (isspace (*bp) && bp > buffer);
                    717: 
                    718:                    if (bp > buffer) {
                    719:                        do {
                    720:                            bp--, w -> _curx--;
                    721:                        } while (!isspace (*bp) && bp > buffer);
                    722:                        if (isspace (*bp))
                    723:                            bp++, w -> _curx++;
                    724:                    }
                    725:                    wclrtoeol (w);
                    726:                    break;
                    727:                }
                    728: 
                    729:                if (c >= ' ' && c < '\177')
                    730:                    (void) waddch (w, *bp++ = c);
                    731:                break;
                    732:        }
                    733: 
                    734:        wrefresh (w);
                    735:     }
                    736: }
                    737: 
                    738: /*  */
                    739: 
                    740: static int
                    741: WINwritev(w, iov, n)
                    742:        register WINDOW *w;
                    743:        register struct iovec *iov;
                    744:        register int n;
                    745: {
                    746:     register int    i;
                    747: 
                    748:     werase (w);
                    749:     wmove (w, 0, 0);
                    750:     for (i = 0; i < n; i++, iov++)
                    751:        wprintw (w, "%*.*s", iov -> iov_len, iov -> iov_len, iov -> iov_base);
                    752:     wrefresh (w);
                    753: 
                    754:     sleep (PAUSE);
                    755: 
                    756:     return OK;
                    757: }
                    758: 
                    759: /*  */
                    760: 
                    761: static struct {
                    762:     char   *h_msg;
                    763:     int    *h_val;
                    764: }               hlpmsg[] = {
                    765:                     "          forward         backwards", NULL,
                    766:                     "          -------         ---------", NULL,
                    767:                     "next screen       SPACE", NULL,
                    768:                     "next %d line%s    RETURN          y", &smallmove,
                    769:                     "next %d line%s    EOT             u", &largemove,
                    770:                     "go                g               G", NULL,
                    771:                     "", NULL,
                    772:                     "refresh           CTRL-L", NULL,
                    773:                     "quit              q", NULL,
                    774: 
                    775:                     NULL, NULL
                    776: };
                    777: 
                    778: /*  */
                    779: 
                    780: static int
                    781: WINless(w, fin)
                    782:        register WINDOW *w;
                    783:        int fin;
                    784: {
                    785:     register int    c,
                    786:                     i,
                    787:                     n;
                    788:     int     nfresh,
                    789: #ifdef notdef
                    790:            nlatch,
                    791: #endif notdef
                    792:             nwait;
                    793:     char   *cp;
                    794:     register struct line   *lbottom;
                    795: 
                    796:     did_less++;
                    797: 
                    798:     cp = NULL;
                    799: #ifdef notdef
                    800:     if (fin)
                    801:        ltop = NULL;
                    802: #endif notdef
                    803:     lbottom = NULL;
                    804:     nfresh = 1;
                    805:     nwait = 0;
                    806:     wrefresh (w);
                    807: 
                    808:     for (;;) {
                    809:        if (nfresh || nwait) {
                    810:            nfresh = 0;
                    811: #ifdef notdef
                    812:            nlatch = 1;
                    813: 
                    814: once_only: ;
                    815: #endif notdef
                    816:            werase (w);
                    817:            wmove (w, 0, 0);
                    818: 
                    819:            if (ltop == NULL)
                    820:                if (fin) {
                    821:                    (void) lgo (ltail -> l_no - w -> _maxy + 1);
                    822:                    if (ltop == NULL)
                    823:                        ltop = lhead;
                    824:                }
                    825:                else
                    826:                    ltop = lbottom && lbottom -> l_prev ? lbottom -> l_prev
                    827:                            : lbottom;
                    828: 
                    829:            for (lbottom = ltop; lbottom; lbottom = lbottom -> l_next)
                    830:                if (waddstr (w, lbottom -> l_buf) == ERR
                    831:                        || waddch (w, '\n') == ERR)
                    832:                    break;
                    833:            if (lbottom == NULL)
                    834:                if (fin) {
                    835: #ifdef notdef
                    836:                    if (nlatch && (ltail -> l_no >= w -> _maxy)) {
                    837:                        (void) lgo (ltail -> l_no - w -> _maxy + 1);
                    838:                        nlatch = 0;
                    839:                        goto once_only;
                    840:                    }
                    841: #endif notdef
                    842:                    lbottom = ltail;
                    843:                    while (waddstr (w, "~\n") != ERR)
                    844:                        continue;
                    845:                }
                    846:                else {
                    847:                    wrefresh (w);
                    848:                    return 0;
                    849:                }
                    850: 
                    851:            if (!nwait)
                    852:                wrefresh (w);
                    853:        }
                    854: 
                    855:        wmove (Command, 0, 0);
                    856:        if (cp) {
                    857:            wstandout (Command);
                    858:            wprintw (Command, "%s", cp);
                    859:            wstandend (Command);
                    860:            cp = NULL;
                    861:        }
                    862:        else
                    863:            wprintw (Command, fin ? "top:%d bot:%d end:%d" : "top:%d bot:%d",
                    864:                    ltop -> l_no, lbottom -> l_no, ltail -> l_no);
                    865:        wprintw (Command, ">> ");
                    866:        wclrtoeol (Command);
                    867:        wrefresh (Command);
                    868: 
                    869:        c = toascii (wgetch (Command));
                    870: 
                    871:        werase (Command);
                    872:        wrefresh (Command);
                    873: 
                    874:        if (nwait) {
                    875:            nwait = 0;
                    876:            wrefresh (w);
                    877:        }
                    878: 
                    879:        n = 0;
                    880: again:         ;
                    881:        switch (c) {
                    882:            case ' ':
                    883:                ltop = lbottom -> l_next;
                    884:                nfresh++;
                    885:                break;
                    886: 
                    887:            case '\r':
                    888:            case '\n':
                    889:            case 'e':
                    890:            case 'j':
                    891:                if (n)
                    892:                    smallmove = n;
                    893:                if (ladvance (smallmove))
                    894:                    nfresh++;
                    895:                break;
                    896: 
                    897:            case 'y':
                    898:            case 'k':
                    899:                if (n)
                    900:                    smallmove = n;
                    901:                if (lretreat (smallmove))
                    902:                    nfresh++;
                    903:                break;
                    904: 
                    905:            case 'd':
                    906:        eof:    ;
                    907:                if (n)
                    908:                    largemove = n;
                    909:                if (ladvance (largemove))
                    910:                    nfresh++;
                    911:                break;
                    912: 
                    913:            case 'u':
                    914:                if (n)
                    915:                    largemove = n;
                    916:                if (lretreat (largemove))
                    917:                    nfresh++;
                    918:                break;
                    919: 
                    920:            case 'g':
                    921:                if (lgo (n ? n : 1))
                    922:                    nfresh++;
                    923:                break;
                    924: 
                    925:            case 'G':
                    926:                if (lgo (n ? n : ltail -> l_no - w -> _maxy + 1))
                    927:                    nfresh++;
                    928:                break;
                    929: 
                    930:            case '\f':
                    931:            case 'r':
                    932:                wrefresh (curscr);
                    933:                break;
                    934: 
                    935:            case 'h':
                    936:            case '?':
                    937:                werase (w);
                    938:                wmove (w, 0, 0);
                    939:                for (i = 0; hlpmsg[i].h_msg; i++) {
                    940:                    if (hlpmsg[i].h_val)
                    941:                        wprintw (w, hlpmsg[i].h_msg, *hlpmsg[i].h_val,
                    942:                                *hlpmsg[i].h_val != 1 ? "s" : "");
                    943:                    else
                    944:                        (void) waddstr (w, hlpmsg[i].h_msg);
                    945:                    (void) waddch (w, '\n');
                    946:                }
                    947:                wrefresh (w);
                    948:                nwait++;
                    949:                break;
                    950: 
                    951:            case 'q':
                    952:                return 1;
                    953: 
                    954:            default:
                    955:                if (c == EOFC)
                    956:                    goto eof;
                    957: 
                    958:                if (isdigit (c)) {
                    959:                    wmove (Command, 0, 0);
                    960:                    i = 0;
                    961:                    while (isdigit (c)) {
                    962:                        wprintw (Command, "%c", c);
                    963:                        wrefresh (Command);
                    964:                        i = i * 10 + c - '0';
                    965:                        c = toascii (wgetch (Command));
                    966:                    }
                    967:                    werase (Command);
                    968:                    wrefresh (Command);
                    969: 
                    970:                    if (i > 0) {
                    971:                        n = i;
                    972:                        goto again;
                    973:                    }
                    974:                    cp = "bad number";
                    975:                }
                    976:                else
                    977:                    cp = "not understood";
                    978:                break;
                    979:        }
                    980:     }
                    981: }
                    982: 
                    983: /*  */
                    984: 
                    985: 
                    986: static int
                    987: WINputc(w, c)
                    988:        register WINDOW *w;
                    989:        register char c;
                    990: {
                    991:     register int    x,
                    992:                     y;
                    993: 
                    994:     if (w != Scan)
                    995:        switch (c) {
                    996:            default:
                    997:                if (c < ' ' || c == '\177')
                    998:                    return (waddch (w, '^') != ERR ? waddch (w, c ^ 0100)
                    999:                            : ERR);/* else fall */
                   1000: 
                   1001:            case '\t':
                   1002:            case '\n':
                   1003:                return waddch (w, c);
                   1004:        }
                   1005: 
                   1006:     if ((x = w -> _curx) < 0 || x >= w -> _maxx
                   1007:            || (y = w -> _cury) < 0 || y >= w -> _maxy)
                   1008:        return DONE;
                   1009: 
                   1010:     switch (c) {
                   1011:        case '\t':
                   1012:            for (x = 8 - (x & 0x07); x > 0; x--)
                   1013:                if (WINputc (w, ' ') == ERR)
                   1014:                    return ERR;
                   1015:            break;
                   1016: 
                   1017:        case '\n':
                   1018:            if (++y < w -> _maxy)
                   1019:                (void) waddch (w, c);
                   1020:            else
                   1021:                wclrtoeol (w);
                   1022:            break;
                   1023: 
                   1024:        default:
                   1025:            if (c < ' ' || c == '\177') {
                   1026:                if (WINputc (w, '^') == ERR || WINputc (w, c ^ 0100) == ERR)
                   1027:                    return ERR;
                   1028:                break;
                   1029:            }
                   1030:            if (++x < w -> _maxx)
                   1031:                (void) waddch (w, c);
                   1032:            break;
                   1033:     }
                   1034:     return DONE;
                   1035: }
                   1036: 
                   1037: /*    LINES */
                   1038: 
                   1039: static void
                   1040: lreset()
                   1041: {
                   1042:     register struct line   *lp,
                   1043:                            *mp;
                   1044: 
                   1045:     for (lp = lhead; lp; lp = mp) {
                   1046:        mp = lp -> l_next;
                   1047:        free (lp -> l_buf);
                   1048:        free ((char *) lp);
                   1049:     }
                   1050:     lhead = ltop = ltail = NULL;
                   1051: }
                   1052: 
                   1053: 
                   1054: static void
                   1055: linsert(w)
                   1056:        WINDOW *w;
                   1057: {
                   1058:     register char  *cp;
                   1059:     register struct line   *lp;
                   1060: 
                   1061:     if ((lp = (struct line  *) calloc ((unsigned) 1, sizeof *lp)) == NULL)
                   1062:        adios (NULLCP, "unable to allocate line storage");
                   1063: 
                   1064:     lp -> l_no = (ltail ? ltail -> l_no : 0) + 1;
                   1065:     lp -> l_buf = getcpy (w -> _y[w -> _cury]);
                   1066:     for (cp = lp -> l_buf + strlen (lp -> l_buf) - 1; cp >= lp -> l_buf; cp--)
                   1067:        if (isspace (*cp))
                   1068:            *cp = NULL;
                   1069:        else
                   1070:            break;
                   1071: 
                   1072:     if (lhead == NULL)
                   1073:        lhead = lp;
                   1074:     if (ltop == NULL)
                   1075:        ltop = lp;
                   1076:     if (ltail)
                   1077:        ltail -> l_next = lp;
                   1078:     lp -> l_prev = ltail;
                   1079:     ltail = lp;
                   1080: }
                   1081: 
                   1082: /*  */
                   1083: 
                   1084: static int
                   1085: ladvance(n)
                   1086:        int n;
                   1087: {
                   1088:     register int    i;
                   1089:     register struct line   *lp;
                   1090: 
                   1091:     for (i = 0, lp = ltop; i < n && lp; i++, lp = lp -> l_next)
                   1092:        continue;
                   1093: 
                   1094:     if (ltop == lp)
                   1095:        return 0;
                   1096: 
                   1097:     ltop = lp;
                   1098:     return 1;
                   1099: }
                   1100: 
                   1101: 
                   1102: static int
                   1103: lretreat(n)
                   1104:        int n;
                   1105: {
                   1106:     register int    i;
                   1107:     register struct line   *lp;
                   1108: 
                   1109:     for (i = 0, lp = ltop; i < n && lp; i++, lp = lp -> l_prev)
                   1110:        if (!lp -> l_prev)
                   1111:            break;
                   1112: 
                   1113:     if (ltop == lp)
                   1114:        return 0;
                   1115: 
                   1116:     ltop = lp;
                   1117:     return 1;
                   1118: }
                   1119: 
                   1120: /*  */
                   1121: 
                   1122: static int
                   1123: lgo(n)
                   1124:        int n;
                   1125: {
                   1126:     register int    i,
                   1127:                     j;
                   1128:     register struct line   *lp;
                   1129: 
                   1130:     if ((i = n - (lp = lhead) -> l_no) > (j = abs (n - ltop -> l_no)))
                   1131:        i = j, lp = ltop;
                   1132:     if (i > (j = abs (ltail -> l_no - n)))
                   1133:        i = j, lp = ltail;
                   1134: 
                   1135:     if (n >= lp -> l_no) {
                   1136:        for (; lp; lp = lp -> l_next)
                   1137:            if (lp -> l_no == n)
                   1138:                break;
                   1139:     }
                   1140:     else {
                   1141:        for (; lp; lp = lp -> l_prev)
                   1142:            if (lp -> l_no == n)
                   1143:                break;
                   1144:        if (!lp)
                   1145:            lp = lhead;
                   1146:     }
                   1147: 
                   1148:     if (ltop == lp)
                   1149:        return 0;
                   1150: 
                   1151:     ltop = lp;
                   1152:     return 1;
                   1153: }
                   1154: 
                   1155: /*    TTYS */
                   1156: 
                   1157: static int
                   1158: TTYinit(nprog)
                   1159: {
                   1160:     if (!isatty (fileno (stdin)) || !isatty (fileno (stdout)))
                   1161:        if (nprog)
                   1162:            return NOTOK;
                   1163:        else
                   1164:            adios (NULLCP, "not a tty");
                   1165: 
                   1166:     foreground ();
                   1167: #ifndef        SYS5
                   1168:     if (ioctl (fileno (stdin), TIOCGETP, (char *) &sg) == NOTOK)
                   1169:        adios ("failed", "ioctl TIOCGETP");
                   1170:     if (ioctl (fileno (stdin), TIOCGETC, (char *) &tc) == NOTOK)
                   1171:        adios ("failed", "ioctl TIOCGETC");
                   1172: #else  SYS5
                   1173:     if (ioctl (fileno (stdin), TCGETA, &sg) == NOTOK)
                   1174:        adios ("failed", "ioctl TCGETA");
                   1175: #endif SYS5
                   1176: #ifdef TIOCGLTC
                   1177:     if (ioctl (fileno (stdin), TIOCGLTC, (char *) &ltc) == NOTOK)
                   1178:        adios ("failed", "ioctl TIOCGLTC");
                   1179: #endif TIOCGLTC
                   1180:     intrc = INTR;
                   1181:     sideground ();
                   1182: 
                   1183:     tty_ready = OK;
                   1184: 
                   1185:     (void) signal (SIGPIPE, PIPEser);
                   1186: 
                   1187:     return OK;
                   1188: }
                   1189: 
                   1190: /*  */
                   1191: 
                   1192: static void
                   1193: TTYon()
                   1194: {
                   1195:     if (tty_ready == DONE)
                   1196:        return;
                   1197: 
                   1198:     INTR = NOTOK;
                   1199: #ifndef        SYS5
                   1200:     (void) ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
                   1201: #else  SYS5
                   1202:     (void) ioctl (fileno (stdin), TCSETA, &sg);
                   1203: #endif SYS5
                   1204: 
                   1205:     (void) crmode ();
                   1206:     (void) noecho ();
                   1207:     (void) nonl ();
                   1208:     scrollok (curscr, FALSE);
                   1209: 
                   1210:     discard (stdin);
                   1211: 
                   1212:     tty_ready = DONE;
                   1213: 
                   1214:     (void) signal (SIGHUP, SIGser);
                   1215:     (void) signal (SIGINT, SIGser);
                   1216:     (void) signal (SIGQUIT, SIGser);
                   1217: #ifdef SIGTSTP
                   1218:     (void) signal (SIGTSTP, TSTPser);
                   1219: #endif SIGTSTP
                   1220: }
                   1221: 
                   1222: /*  */
                   1223: 
                   1224: static void
                   1225: TTYoff()
                   1226: {
                   1227:     if (tty_ready == NOTOK)
                   1228:        return;
                   1229: 
                   1230:     INTR = intrc;
                   1231: #ifndef        SYS5
                   1232:     (void) ioctl (fileno (stdin), TIOCSETC, (char *) &tc);
                   1233: #else  SYS5
                   1234:     (void) ioctl (fileno (stdin), TCSETA, &sg);
                   1235: #endif SYS5
                   1236: 
                   1237:     leaveok (curscr, TRUE);
                   1238:     mvcur (0, COLS - 1, LINES - 1, 0);
                   1239:     endwin ();
                   1240:     if (tty_ready == DONE) {
                   1241: #ifndef        SYS5
                   1242:        if (CE)
                   1243:            tputs (CE, 0, _putchar);
                   1244:        else
                   1245: #endif SYS5
                   1246:            fprintf (stdout, "\r\n");
                   1247:     }
                   1248:     (void) fflush (stdout);
                   1249: 
                   1250:     tty_ready = NOTOK;
                   1251: 
                   1252:     (void) signal (SIGHUP, SIG_DFL);
                   1253:     (void) signal (SIGINT, SIG_DFL);
                   1254:     (void) signal (SIGQUIT, SIG_DFL);
                   1255: #ifdef SIGTSTP
                   1256:     (void) signal (SIGTSTP, SIG_DFL);
                   1257: #endif SIGTSTP
                   1258: }
                   1259: 
                   1260: /*  */
                   1261: 
                   1262: static void
                   1263: foreground()
                   1264: {
                   1265: #ifdef TIOCGPGRP
                   1266:     int     pgrp,
                   1267:             tpgrp;
                   1268:     SIGDECL (*tstat)();
                   1269: 
                   1270:     if ((pgrp = getpgrp (0)) == NOTOK)
                   1271:        adios ("process group", "unable to determine");
                   1272:     for (;;) {
                   1273:        if (ioctl (fileno (stdin), TIOCGPGRP, (char *) &tpgrp) == NOTOK)
                   1274:            adios ("tty's process group", "unable to determine");
                   1275:        if (pgrp == tpgrp)
                   1276:            break;
                   1277: 
                   1278:        tstat = signal (SIGTTIN, SIG_DFL);
                   1279:        (void) kill (0, SIGTTIN);
                   1280:        (void) signal (SIGTTIN, tstat);
                   1281:     }
                   1282: 
                   1283:     (void) signal (SIGTTIN, SIG_IGN);
                   1284:     (void) signal (SIGTTOU, SIG_IGN);
                   1285:     (void) signal (SIGTSTP, SIG_IGN);
                   1286: #endif TIOCGPGRP
                   1287: }
                   1288: 
                   1289: static void
                   1290: sideground()
                   1291: {
                   1292: #ifdef TIOCGPGRP
                   1293:     (void) signal (SIGTTIN, SIG_DFL);
                   1294:     (void) signal (SIGTTOU, SIG_DFL);
                   1295:     (void) signal (SIGTSTP, SIG_DFL);
                   1296: #endif TIOCGPGRP
                   1297: }
                   1298: 
                   1299: /*    SIGNALS */
                   1300: 
                   1301: /* ARGSUSED */
                   1302: 
                   1303: static int
                   1304: ALRMser(sig)
                   1305:        int sig;
                   1306: {
                   1307:      longjmp (PEERctx, DONE);
                   1308: }
                   1309: 
                   1310: 
                   1311: #ifdef BSD42
                   1312: /* ARGSUSED */
                   1313: #endif BSD42
                   1314: 
                   1315: static int
                   1316: PIPEser(sig)
                   1317:        int sig;
                   1318: {
                   1319: #ifndef        BSD42
                   1320:     (void) signal (sig, SIG_IGN);
                   1321: #endif BSD42
                   1322: 
                   1323:     adios (NULLCP, "lost peer");
                   1324: }
                   1325: 
                   1326: 
                   1327: #ifdef BSD42
                   1328: /* ARGSUSED */
                   1329: #endif BSD42
                   1330: 
                   1331: static int
                   1332: SIGser(sig)
                   1333:        int sig;
                   1334: {
                   1335: #ifndef        BSD42
                   1336:     (void) signal (sig, SIG_IGN);
                   1337: #endif BSD42
                   1338: 
                   1339:     done (1);
                   1340: }
                   1341: 
                   1342: 
                   1343: #ifdef SIGTSTP
                   1344: static int
                   1345: TSTPser(sig)
                   1346:        int sig;
                   1347: {
                   1348:     tputs (tgoto (CM, 0, LINES - 1), 0, _putchar);
                   1349:     (void) fflush (stdout);
                   1350: 
                   1351:     TTYoff ();
                   1352: #ifdef BSD42
                   1353:     (void) sigsetmask (sigblock (0) & ~sigmask (SIGTSTP));
                   1354: #endif BSD42
                   1355: 
                   1356:     (void) kill (getpid (), sig);
                   1357: 
                   1358: #ifdef BSD42
                   1359:     (void) sigblock (sigmask (SIGTSTP));
                   1360: #endif BSD42
                   1361:     TTYon ();
                   1362: 
                   1363:     wrefresh (curscr);
                   1364: }
                   1365: #endif SIGTSTP
                   1366: 
                   1367: /*    MISCELLANY */
                   1368: 
                   1369: void
                   1370: done (status)
                   1371:        int status;
                   1372: {
                   1373:     TTYoff ();
                   1374:     (void) pFIN ();
                   1375: 
                   1376:     exit (status);
                   1377: }
                   1378: 
                   1379: /*  */
                   1380: 
                   1381: /* VARARGS2 */
                   1382: 
                   1383: static void
                   1384: adorn(what, fmt, a, b, c, d, e, f)
                   1385:        char *what, *fmt, *a, *b, *c, *d, *e, *f;
                   1386: {
                   1387:     char   *cp = invo_name;
                   1388: 
                   1389:     invo_name = NULL;
                   1390:     advise (what, fmt, a, b, c, d, e, f);
                   1391:     invo_name = cp;
                   1392: }
                   1393: 
                   1394: /*  */
                   1395: 
                   1396: /* VARARGS3 */
                   1397: void
                   1398: advertise(what, tail, fmt, a, b, c, d, e, f)
                   1399:        char *what, *tail, *fmt, *a, *b, *c, *d, *e, *f;
                   1400: {
                   1401:     int            eindex = errno;
                   1402:     char    buffer[BUFSIZ],
                   1403:             err[BUFSIZ];
                   1404:     struct iovec    iob[20];
                   1405:     register struct iovec  *iov = iob;
                   1406: 
                   1407:     (void) fflush (stdout);
                   1408: 
                   1409:     (void) fflush (stderr);
                   1410: 
                   1411:     if (invo_name) {
                   1412:        iov -> iov_len = strlen (iov -> iov_base = invo_name);
                   1413:        iov++;
                   1414:        iov -> iov_len = strlen (iov -> iov_base = ": ");
                   1415:        iov++;
                   1416:     }
                   1417: 
                   1418:     (void) sprintf (buffer, fmt, a, b, c, d, e, f);
                   1419:     iov -> iov_len = strlen (iov -> iov_base = buffer);
                   1420:     iov++;
                   1421:     if (what) {
                   1422:        if (*what) {
                   1423:            iov -> iov_len = strlen (iov -> iov_base = " ");
                   1424:            iov++;
                   1425:            iov -> iov_len = strlen (iov -> iov_base = what);
                   1426:            iov++;
                   1427:            iov -> iov_len = strlen (iov -> iov_base = ": ");
                   1428:            iov++;
                   1429:        }
                   1430:        if (eindex > 0 && eindex < sys_nerr)
                   1431:            iov -> iov_len = strlen (iov -> iov_base = sys_errlist[eindex]);
                   1432:        else {
                   1433:            (void) sprintf (err, "Error %d", eindex);
                   1434:            iov -> iov_len = strlen (iov -> iov_base = err);
                   1435:        }
                   1436:        iov++;
                   1437:     }
                   1438:     if (tail && *tail) {
                   1439:        iov -> iov_len = strlen (iov -> iov_base = ", ");
                   1440:        iov++;
                   1441:        iov -> iov_len = strlen (iov -> iov_base = tail);
                   1442:        iov++;
                   1443:     }
                   1444:     iov -> iov_len = strlen (iov -> iov_base = "\n");
                   1445:     iov++;
                   1446: 
                   1447:     if (tty_ready == DONE)
                   1448:        (void) WINwritev (Display, iob, iov - iob);
                   1449:     else
                   1450:        (void) writev (fileno (stderr), iob, iov - iob);
                   1451: }
                   1452: 
                   1453: /*  */
                   1454: 
                   1455: #ifndef        BSD42
                   1456: static int
                   1457: writev(fd, iov, n)
                   1458:        register int fd;
                   1459:        register struct iovec *iov;
                   1460:        register int n;
                   1461: {
                   1462:     register int    i,
                   1463:                     j;
                   1464: 
                   1465:     for (i = j = 0; i < n; i++, iov++)
                   1466:        if (write (fd, iov -> iov_base, iov -> iov_len) != iov -> iov_len)
                   1467:            break;
                   1468:        else
                   1469:            j += iov -> iov_len;
                   1470: 
                   1471:     return j;
                   1472: }
                   1473: #endif BSD42

unix.superglobalmegacorp.com

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