Annotation of 43BSDTahoe/ucb/ex/ex_temp.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Copyright (c) 1980 Regents of the University of California.
                      3:  * All rights reserved.  The Berkeley software License Agreement
                      4:  * specifies the terms and conditions for redistribution.
                      5:  */
                      6: 
                      7: #ifndef lint
                      8: static char *sccsid = "@(#)ex_temp.c   7.6 (Berkeley) 3/9/87";
                      9: #endif not lint
                     10: 
                     11: #include "ex.h"
                     12: #include "ex_temp.h"
                     13: #include "ex_vis.h"
                     14: #include "ex_tty.h"
                     15: 
                     16: /*
                     17:  * Editor temporary file routines.
                     18:  * Very similar to those of ed, except uses 2 input buffers.
                     19:  */
                     20: #define        READ    0
                     21: #define        WRITE   1
                     22: 
                     23: #ifndef vms
                     24: #define        EPOSITION       7
                     25: #else
                     26: #define        EPOSITION       13
                     27: #endif
                     28: 
                     29: char   tfname[40];
                     30: char   rfname[40];
                     31: int    havetmp;
                     32: short  tfile = -1;
                     33: short  rfile = -1;
                     34: 
                     35: fileinit()
                     36: {
                     37:        register char *p;
                     38:        register int i, j;
                     39:        struct stat stbuf;
                     40: 
                     41:        if (tline == INCRMT * (HBLKS+2))
                     42:                return;
                     43:        cleanup(0);
                     44:        if (tfile >= 0)
                     45:                close(tfile);
                     46:        tline = INCRMT * (HBLKS+2);
                     47:        blocks[0] = HBLKS;
                     48:        blocks[1] = HBLKS+1;
                     49:        blocks[2] = -1;
                     50:        dirtcnt = 0;
                     51:        iblock = -1;
                     52:        iblock2 = -1;
                     53:        oblock = -1;
                     54:        CP(tfname, svalue(DIRECTORY));
                     55: #ifndef vms
                     56:        if (stat(tfname, &stbuf))
                     57: #else
                     58:        goto vms_no_check_dir;
                     59: #endif
                     60:        {
                     61: dumbness:
                     62:                if (setexit() == 0)
                     63:                        filioerr(tfname);
                     64:                else
                     65:                        putNFL();
                     66:                cleanup(1);
                     67:                ex_exit(1);
                     68:        }
                     69: #ifndef        vms
                     70:        if ((stbuf.st_mode & S_IFMT) != S_IFDIR) {
                     71:                errno = ENOTDIR;
                     72:                goto dumbness;
                     73:        }
                     74: #else
                     75: vms_no_check_dir:
                     76: #endif
                     77:        ichanged = 0;
                     78:        ichang2 = 0;
                     79: #ifndef        vms
                     80:        ignore(strcat(tfname, "/ExXXXXX"));
                     81: #else
                     82:        ignore(strcat(tfname, "ExXXXXX"));
                     83: #endif
                     84:        for (p = strend(tfname), i = 5, j = getpid(); i > 0; i--, j /= 10)
                     85:                *--p = j % 10 | '0';
                     86: #ifdef vms
                     87:        ignore(strcat(tfname, ".txt.1"));
                     88:        unlink(tfname);
                     89: #endif
                     90:        tfile = creat(tfname, 0600);
                     91:        if (tfile < 0)
                     92:                goto dumbness;
                     93: #ifdef VMUNIX
                     94:        {
                     95:                extern stilinc;         /* see below */
                     96:                stilinc = 0;
                     97:        }
                     98: #endif
                     99:        havetmp = 1;
                    100:        if (tfile >= 0)
                    101:                close(tfile);
                    102:        tfile = open(tfname, 2);
                    103:        if (tfile < 0)
                    104:                goto dumbness;
                    105: #ifdef UNIX_SBRK
                    106: /*     brk((char *)fendcore); */
                    107: #endif
                    108: }
                    109: 
                    110: cleanup(all)
                    111:        bool all;
                    112: {
                    113:        if (all) {
                    114:                putpad(TE);
                    115:                flush();
                    116:        }
                    117:        if (havetmp) {
                    118:                if (tfile >= 0)
                    119:                        close(tfile);
                    120:                unlink(tfname);
                    121:        }
                    122:        havetmp = 0;
                    123:        if (all && rfile >= 0) {
                    124:                if (rfile >= 0)
                    125:                        close(rfile);
                    126:                unlink(rfname);
                    127:                rfile = -1;
                    128:        }
                    129: }
                    130: 
                    131: getline(tl)
                    132:        line tl;
                    133: {
                    134:        register char *bp, *lp;
                    135:        register int nl;
                    136: 
                    137:        lp = linebuf;
                    138:        bp = getblock(tl, READ);
                    139:        nl = nleft;
                    140:        tl &= ~OFFMSK;
                    141:        while (*lp++ = *bp++)
                    142:                if (--nl == 0) {
                    143:                        bp = getblock(tl += INCRMT, READ);
                    144:                        nl = nleft;
                    145:                }
                    146: }
                    147: 
                    148: putline()
                    149: {
                    150:        register char *bp, *lp;
                    151:        register int nl;
                    152:        line tl;
                    153: 
                    154:        dirtcnt++;
                    155:        lp = linebuf;
                    156:        change();
                    157:        tl = tline;
                    158:        bp = getblock(tl, WRITE);
                    159:        nl = nleft;
                    160:        tl &= ~OFFMSK;
                    161:        while (*bp = *lp++) {
                    162:                if (*bp++ == '\n') {
                    163:                        *--bp = 0;
                    164:                        linebp = lp;
                    165:                        break;
                    166:                }
                    167:                if (--nl == 0) {
                    168:                        bp = getblock(tl += INCRMT, WRITE);
                    169:                        nl = nleft;
                    170:                }
                    171:        }
                    172:        tl = tline;
                    173:        tline += (((lp - linebuf) + BNDRY - 1) >> SHFT) & 077776;
                    174:        return (tl);
                    175: }
                    176: 
                    177: int    read();
                    178: int    write();
                    179: 
                    180: char *
                    181: getblock(atl, iof)
                    182:        line atl;
                    183:        int iof;
                    184: {
                    185:        register int bno, off;
                    186: #ifdef CRYPT
                    187:         register char *p1, *p2;
                    188:         register int n;
                    189: #endif
                    190:        
                    191:        bno = (atl >> OFFBTS) & BLKMSK;
                    192:        off = (atl << SHFT) & LBTMSK;
                    193:        if (bno >= NMBLKS)
                    194:                error(" Tmp file too large");
                    195:        nleft = BUFSIZ - off;
                    196:        if (bno == iblock) {
                    197:                ichanged |= iof;
                    198:                hitin2 = 0;
                    199:                return (ibuff + off);
                    200:        }
                    201:        if (bno == iblock2) {
                    202:                ichang2 |= iof;
                    203:                hitin2 = 1;
                    204:                return (ibuff2 + off);
                    205:        }
                    206:        if (bno == oblock)
                    207:                return (obuff + off);
                    208:        if (iof == READ) {
                    209:                if (hitin2 == 0) {
                    210:                        if (ichang2) {
                    211: #ifdef CRYPT
                    212:                                if(xtflag)
                    213:                                        crblock(tperm, ibuff2, CRSIZE, (long)0);
                    214: #endif
                    215:                                blkio(iblock2, ibuff2, write);
                    216:                        }
                    217:                        ichang2 = 0;
                    218:                        iblock2 = bno;
                    219:                        blkio(bno, ibuff2, read);
                    220: #ifdef CRYPT
                    221:                        if(xtflag)
                    222:                                crblock(tperm, ibuff2, CRSIZE, (long)0);
                    223: #endif
                    224:                        hitin2 = 1;
                    225:                        return (ibuff2 + off);
                    226:                }
                    227:                hitin2 = 0;
                    228:                if (ichanged) {
                    229: #ifdef CRYPT
                    230:                        if(xtflag)
                    231:                                crblock(tperm, ibuff, CRSIZE, (long)0);
                    232: #endif
                    233:                        blkio(iblock, ibuff, write);
                    234:                }
                    235:                ichanged = 0;
                    236:                iblock = bno;
                    237:                blkio(bno, ibuff, read);
                    238: #ifdef CRYPT
                    239:                if(xtflag)
                    240:                        crblock(tperm, ibuff, CRSIZE, (long)0);
                    241: #endif
                    242:                return (ibuff + off);
                    243:        }
                    244:        if (oblock >= 0) {
                    245: #ifdef CRYPT
                    246:                if(xtflag) {
                    247:                        /*
                    248:                         * Encrypt block before writing, so some devious
                    249:                         * person can't look at temp file while editing.
                    250:                         */
                    251:                        p1 = obuff;
                    252:                        p2 = crbuf;
                    253:                        n = CRSIZE;
                    254:                        while(n--)
                    255:                                *p2++ = *p1++;
                    256:                        crblock(tperm, crbuf, CRSIZE, (long)0);
                    257:                        blkio(oblock, crbuf, write);
                    258:                } else
                    259: #endif
                    260:                        blkio(oblock, obuff, write);
                    261:        }
                    262:        oblock = bno;
                    263:        return (obuff + off);
                    264: }
                    265: 
                    266: #ifdef VMUNIX
                    267: #ifdef vms
                    268: #define        INCORB  32
                    269: #else
                    270: #define        INCORB  64
                    271: #endif
                    272: char   incorb[INCORB+1][BUFSIZ];
                    273: #define        pagrnd(a)       ((char *)(((int)a)&~(BUFSIZ-1)))
                    274: int    stilinc;        /* up to here not written yet */
                    275: #endif
                    276: 
                    277: blkio(b, buf, iofcn)
                    278:        short b;
                    279:        char *buf;
                    280:        int (*iofcn)();
                    281: {
                    282: 
                    283: #ifdef VMUNIX
                    284:        if (b < INCORB) {
                    285:                if (iofcn == read) {
                    286:                        bcopy(pagrnd(incorb[b+1]), buf, BUFSIZ);
                    287:                        return;
                    288:                }
                    289:                bcopy(buf, pagrnd(incorb[b+1]), BUFSIZ);
                    290:                if (laste) {
                    291:                        if (b >= stilinc)
                    292:                                stilinc = b + 1;
                    293:                        return;
                    294:                }
                    295:        } else if (stilinc)
                    296:                tflush();
                    297: #endif
                    298:        lseek(tfile, (long) (unsigned) b * BUFSIZ, 0);
                    299:        if ((*iofcn)(tfile, buf, BUFSIZ) != BUFSIZ)
                    300:                filioerr(tfname);
                    301: }
                    302: 
                    303: #ifdef VMUNIX
                    304: tlaste()
                    305: {
                    306: 
                    307:        if (stilinc)
                    308:                dirtcnt = 0;
                    309: }
                    310: 
                    311: tflush()
                    312: {
                    313:        int i = stilinc;
                    314:        
                    315:        stilinc = 0;
                    316:        lseek(tfile, (long) 0, 0);
                    317:        if (write(tfile, pagrnd(incorb[1]), i * BUFSIZ) != (i * BUFSIZ))
                    318:                filioerr(tfname);
                    319: }
                    320: #endif
                    321: 
                    322: /*
                    323:  * Synchronize the state of the temporary file in case
                    324:  * a crash occurs.
                    325:  */
                    326: synctmp()
                    327: {
                    328:        register int cnt;
                    329:        register line *a;
                    330:        register short *bp;
                    331: 
                    332: #ifdef VMUNIX
                    333:        if (stilinc)
                    334:                return;
                    335: #endif
                    336:        if (dol == zero)
                    337:                return;
                    338:        if (ichanged)
                    339:                blkio(iblock, ibuff, write);
                    340:        ichanged = 0;
                    341:        if (ichang2)
                    342:                blkio(iblock2, ibuff2, write);
                    343:        ichang2 = 0;
                    344:        if (oblock != -1)
                    345:                blkio(oblock, obuff, write);
                    346:        time(&H.Time);
                    347:        uid = getuid();
                    348:        *zero = (line) H.Time;
                    349:        for (a = zero, bp = blocks; a <= dol; a += BUFSIZ / sizeof *a, bp++) {
                    350:                if (*bp < 0) {
                    351:                        tline = (tline + OFFMSK) &~ OFFMSK;
                    352:                        *bp = ((tline >> OFFBTS) & BLKMSK);
                    353:                        if (*bp > NMBLKS)
                    354:                                error(" Tmp file too large");
                    355:                        tline += INCRMT;
                    356:                        oblock = *bp + 1;
                    357:                        bp[1] = -1;
                    358:                }
                    359:                lseek(tfile, (long) (unsigned) *bp * BUFSIZ, 0);
                    360:                cnt = ((dol - a) + 2) * sizeof (line);
                    361:                if (cnt > BUFSIZ)
                    362:                        cnt = BUFSIZ;
                    363:                if (write(tfile, (char *) a, cnt) != cnt) {
                    364: oops:
                    365:                        *zero = 0;
                    366:                        filioerr(tfname);
                    367:                }
                    368:                *zero = 0;
                    369:        }
                    370:        flines = lineDOL();
                    371:        lseek(tfile, 0l, 0);
                    372:        if (write(tfile, (char *) &H, sizeof H) != sizeof H)
                    373:                goto oops;
                    374: #ifdef notdef
                    375:        /*
                    376:         * This will insure that exrecover gets as much
                    377:         * back after a crash as is absolutely possible,
                    378:         * but can result in pregnant pauses between commands
                    379:         * when the TSYNC call is made, so...
                    380:         */
                    381: #ifndef vms
                    382:        (void) fsync(tfile);
                    383: #endif
                    384: #endif
                    385: }
                    386: 
                    387: TSYNC()
                    388: {
                    389: 
                    390:        if (dirtcnt > MAXDIRT) {        /* mjm: 12 --> MAXDIRT */
                    391: #ifdef VMUNIX
                    392:                if (stilinc)
                    393:                        tflush();
                    394: #endif
                    395:                dirtcnt = 0;
                    396:                synctmp();
                    397:        }
                    398: }
                    399: 
                    400: /*
                    401:  * Named buffer routines.
                    402:  * These are implemented differently than the main buffer.
                    403:  * Each named buffer has a chain of blocks in the register file.
                    404:  * Each block contains roughly 508 chars of text,
                    405:  * and a previous and next block number.  We also have information
                    406:  * about which blocks came from deletes of multiple partial lines,
                    407:  * e.g. deleting a sentence or a LISP object.
                    408:  *
                    409:  * We maintain a free map for the temp file.  To free the blocks
                    410:  * in a register we must read the blocks to find how they are chained
                    411:  * together.
                    412:  *
                    413:  * BUG:                The default savind of deleted lines in numbered
                    414:  *             buffers may be rather inefficient; it hasn't been profiled.
                    415:  */
                    416: struct strreg {
                    417:        short   rg_flags;
                    418:        short   rg_nleft;
                    419:        short   rg_first;
                    420:        short   rg_last;
                    421: } strregs[('z'-'a'+1) + ('9'-'0'+1)], *strp;
                    422: 
                    423: struct rbuf {
                    424:        short   rb_prev;
                    425:        short   rb_next;
                    426:        char    rb_text[BUFSIZ - 2 * sizeof (short)];
                    427: } *rbuf, KILLrbuf, putrbuf, YANKrbuf, regrbuf;
                    428: #ifdef VMUNIX
                    429: short  rused[256];
                    430: #else
                    431: short  rused[32];
                    432: #endif
                    433: short  rnleft;
                    434: short  rblock;
                    435: short  rnext;
                    436: char   *rbufcp;
                    437: 
                    438: regio(b, iofcn)
                    439:        short b;
                    440:        int (*iofcn)();
                    441: {
                    442: 
                    443:        if (rfile == -1) {
                    444:                CP(rfname, tfname);
                    445:                *(strend(rfname) - EPOSITION) = 'R';
                    446:                rfile = creat(rfname, 0600);
                    447:                if (rfile < 0)
                    448: oops:
                    449:                        filioerr(rfname);
                    450:                else
                    451:                        close(rfile);
                    452:                rfile = open(rfname, 2);
                    453:                if (rfile < 0)
                    454:                        goto oops;
                    455:        }
                    456:        lseek(rfile, (long) b * BUFSIZ, 0);
                    457:        if ((*iofcn)(rfile, rbuf, BUFSIZ) != BUFSIZ)
                    458:                goto oops;
                    459:        rblock = b;
                    460: }
                    461: 
                    462: REGblk()
                    463: {
                    464:        register int i, j, m;
                    465: 
                    466:        for (i = 0; i < sizeof rused / sizeof rused[0]; i++) {
                    467:                m = (rused[i] ^ 0177777) & 0177777;
                    468:                if (i == 0)
                    469:                        m &= ~1;
                    470:                if (m != 0) {
                    471:                        j = 0;
                    472:                        while ((m & 1) == 0)
                    473:                                j++, m >>= 1;
                    474:                        rused[i] |= (1 << j);
                    475: #ifdef RDEBUG
                    476:                        ex_printf("allocating block %d\n", i * 16 + j);
                    477: #endif
                    478:                        return (i * 16 + j);
                    479:                }
                    480:        }
                    481:        error("Out of register space (ugh)");
                    482:        /*NOTREACHED*/
                    483: }
                    484: 
                    485: struct strreg *
                    486: mapreg(c)
                    487:        register int c;
                    488: {
                    489: 
                    490:        if (isupper(c))
                    491:                c = tolower(c);
                    492:        return (isdigit(c) ? &strregs[('z'-'a'+1)+(c-'0')] : &strregs[c-'a']);
                    493: }
                    494: 
                    495: int    shread();
                    496: 
                    497: KILLreg(c)
                    498:        register int c;
                    499: {
                    500:        register struct strreg *sp;
                    501: 
                    502:        rbuf = &KILLrbuf;
                    503:        sp = mapreg(c);
                    504:        rblock = sp->rg_first;
                    505:        sp->rg_first = sp->rg_last = 0;
                    506:        sp->rg_flags = sp->rg_nleft = 0;
                    507:        while (rblock != 0) {
                    508: #ifdef RDEBUG
                    509:                ex_printf("freeing block %d\n", rblock);
                    510: #endif
                    511:                rused[rblock / 16] &= ~(1 << (rblock % 16));
                    512:                regio(rblock, shread);
                    513:                rblock = rbuf->rb_next;
                    514:        }
                    515: }
                    516: 
                    517: /*VARARGS*/
                    518: shread()
                    519: {
                    520:        struct front { short a; short b; };
                    521: 
                    522:        if (read(rfile, (char *) rbuf, sizeof (struct front)) == sizeof (struct front))
                    523:                return (sizeof (struct rbuf));
                    524:        return (0);
                    525: }
                    526: 
                    527: int    getREG();
                    528: 
                    529: putreg(c)
                    530:        char c;
                    531: {
                    532:        register line *odot = dot;
                    533:        register line *odol = dol;
                    534:        register int cnt;
                    535: 
                    536:        deletenone();
                    537:        appendnone();
                    538:        rbuf = &putrbuf;
                    539:        rnleft = 0;
                    540:        rblock = 0;
                    541:        rnext = mapreg(c)->rg_first;
                    542:        if (rnext == 0) {
                    543:                if (inopen) {
                    544:                        splitw++;
                    545:                        vclean();
                    546:                        vgoto(WECHO, 0);
                    547:                }
                    548:                vreg = -1;
                    549:                error("Nothing in register %c", c);
                    550:        }
                    551:        if (inopen && partreg(c)) {
                    552:                if (!FIXUNDO) {
                    553:                        splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
                    554:                        error("Can't put partial line inside macro");
                    555:                }
                    556:                squish();
                    557:                addr1 = addr2 = dol;
                    558:        }
                    559:        cnt = append(getREG, addr2);
                    560:        if (inopen && partreg(c)) {
                    561:                unddol = dol;
                    562:                dol = odol;
                    563:                dot = odot;
                    564:                pragged(0);
                    565:        }
                    566:        killcnt(cnt);
                    567:        notecnt = cnt;
                    568: }
                    569: 
                    570: partreg(c)
                    571:        char c;
                    572: {
                    573: 
                    574:        return (mapreg(c)->rg_flags);
                    575: }
                    576: 
                    577: notpart(c)
                    578:        register int c;
                    579: {
                    580: 
                    581:        if (c)
                    582:                mapreg(c)->rg_flags = 0;
                    583: }
                    584: 
                    585: getREG()
                    586: {
                    587:        register char *lp = linebuf;
                    588:        register int c;
                    589: 
                    590:        for (;;) {
                    591:                if (rnleft == 0) {
                    592:                        if (rnext == 0)
                    593:                                return (EOF);
                    594:                        regio(rnext, read);
                    595:                        rnext = rbuf->rb_next;
                    596:                        rbufcp = rbuf->rb_text;
                    597:                        rnleft = sizeof rbuf->rb_text;
                    598:                }
                    599:                c = *rbufcp;
                    600:                if (c == 0)
                    601:                        return (EOF);
                    602:                rbufcp++, --rnleft;
                    603:                if (c == '\n') {
                    604:                        *lp++ = 0;
                    605:                        return (0);
                    606:                }
                    607:                *lp++ = c;
                    608:        }
                    609: }
                    610: 
                    611: YANKreg(c)
                    612:        register int c;
                    613: {
                    614:        register line *addr;
                    615:        register struct strreg *sp;
                    616:        char savelb[LBSIZE];
                    617: 
                    618:        if (isdigit(c))
                    619:                kshift();
                    620:        if (islower(c))
                    621:                KILLreg(c);
                    622:        strp = sp = mapreg(c);
                    623:        sp->rg_flags = inopen && cursor && wcursor;
                    624:        rbuf = &YANKrbuf;
                    625:        if (sp->rg_last) {
                    626:                regio(sp->rg_last, read);
                    627:                rnleft = sp->rg_nleft;
                    628:                rbufcp = &rbuf->rb_text[sizeof rbuf->rb_text - rnleft];
                    629:        } else {
                    630:                rblock = 0;
                    631:                rnleft = 0;
                    632:        }
                    633:        CP(savelb,linebuf);
                    634:        for (addr = addr1; addr <= addr2; addr++) {
                    635:                getline(*addr);
                    636:                if (sp->rg_flags) {
                    637:                        if (addr == addr2)
                    638:                                *wcursor = 0;
                    639:                        if (addr == addr1)
                    640:                                strcpy(linebuf, cursor);
                    641:                }
                    642:                YANKline();
                    643:        }
                    644:        rbflush();
                    645:        killed();
                    646:        CP(linebuf,savelb);
                    647: }
                    648: 
                    649: kshift()
                    650: {
                    651:        register int i;
                    652: 
                    653:        KILLreg('9');
                    654:        for (i = '8'; i >= '0'; i--)
                    655:                copy(mapreg(i+1), mapreg(i), sizeof (struct strreg));
                    656: }
                    657: 
                    658: YANKline()
                    659: {
                    660:        register char *lp = linebuf;
                    661:        register struct rbuf *rp = rbuf;
                    662:        register int c;
                    663: 
                    664:        do {
                    665:                c = *lp++;
                    666:                if (c == 0)
                    667:                        c = '\n';
                    668:                if (rnleft == 0) {
                    669:                        rp->rb_next = REGblk();
                    670:                        rbflush();
                    671:                        rblock = rp->rb_next;
                    672:                        rp->rb_next = 0;
                    673:                        rp->rb_prev = rblock;
                    674:                        rnleft = sizeof rp->rb_text;
                    675:                        rbufcp = rp->rb_text;
                    676:                }
                    677:                *rbufcp++ = c;
                    678:                --rnleft;
                    679:        } while (c != '\n');
                    680:        if (rnleft)
                    681:                *rbufcp = 0;
                    682: }
                    683: 
                    684: rbflush()
                    685: {
                    686:        register struct strreg *sp = strp;
                    687: 
                    688:        if (rblock == 0)
                    689:                return;
                    690:        regio(rblock, write);
                    691:        if (sp->rg_first == 0)
                    692:                sp->rg_first = rblock;
                    693:        sp->rg_last = rblock;
                    694:        sp->rg_nleft = rnleft;
                    695: }
                    696: 
                    697: /* Register c to char buffer buf of size buflen */
                    698: regbuf(c, buf, buflen)
                    699: char c;
                    700: char *buf;
                    701: int buflen;
                    702: {
                    703:        register char *p, *lp;
                    704: 
                    705:        rbuf = &regrbuf;
                    706:        rnleft = 0;
                    707:        rblock = 0;
                    708:        rnext = mapreg(c)->rg_first;
                    709:        if (rnext==0) {
                    710:                *buf = 0;
                    711:                error("Nothing in register %c",c);
                    712:        }
                    713:        p = buf;
                    714:        while (getREG()==0) {
                    715:                for (lp=linebuf; *lp;) {
                    716:                        if (p >= &buf[buflen])
                    717:                                error("Register too long@to fit in memory");
                    718:                        *p++ = *lp++;
                    719:                }
                    720:                *p++ = '\n';
                    721:        }
                    722:        if (partreg(c)) p--;
                    723:        *p = '\0';
                    724:        getDOT();
                    725: }
                    726: 
                    727: /*
                    728:  * Encryption routines.  These are essentially unmodified from ed.
                    729:  */
                    730: 
                    731: #ifdef CRYPT
                    732: /*
                    733:  * crblock: encrypt/decrypt a block of text.
                    734:  * buf is the buffer through which the text is both input and
                    735:  * output. nchar is the size of the buffer. permp is a work
                    736:  * buffer, and startn is the beginning of a sequence.
                    737:  */
                    738: crblock(permp, buf, nchar, startn)
                    739: char *permp;
                    740: char *buf;
                    741: int nchar;
                    742: long startn;
                    743: {
                    744:        register char *p1;
                    745:        int n1;
                    746:        int n2;
                    747:        register char *t1, *t2, *t3;
                    748: 
                    749:        t1 = permp;
                    750:        t2 = &permp[256];
                    751:        t3 = &permp[512];
                    752: 
                    753:        n1 = startn&0377;
                    754:        n2 = (startn>>8)&0377;
                    755:        p1 = buf;
                    756:        while(nchar--) {
                    757:                *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
                    758:                n1++;
                    759:                if(n1==256){
                    760:                        n1 = 0;
                    761:                        n2++;
                    762:                        if(n2==256) n2 = 0;
                    763:                }
                    764:                p1++;
                    765:        }
                    766: }
                    767: 
                    768: /*
                    769:  * makekey: initialize buffers based on user key a.
                    770:  */
                    771: makekey(a, b)
                    772: char *a, *b;
                    773: {
                    774:        register int i;
                    775:        long t;
                    776:        char temp[KSIZE + 1];
                    777: 
                    778:        for(i = 0; i < KSIZE; i++)
                    779:                temp[i] = *a++;
                    780:        time(&t);
                    781:        t += getpid();
                    782:        for(i = 0; i < 4; i++)
                    783:                temp[i] ^= (t>>(8*i))&0377;
                    784:        crinit(temp, b);
                    785: }
                    786: 
                    787: /*
                    788:  * crinit: besides initializing the encryption machine, this routine
                    789:  * returns 0 if the key is null, and 1 if it is non-null.
                    790:  */
                    791: crinit(keyp, permp)
                    792: char    *keyp, *permp;
                    793: {
                    794:        register char *t1, *t2, *t3;
                    795:        register i;
                    796:        int ic, k, temp;
                    797:        unsigned random;
                    798:        char buf[13];
                    799:        long seed;
                    800: 
                    801:        t1 = permp;
                    802:        t2 = &permp[256];
                    803:        t3 = &permp[512];
                    804:        if(*keyp == 0)
                    805:                return(0);
                    806:        strncpy(buf, keyp, 8);
                    807:        while (*keyp)
                    808:                *keyp++ = '\0';
                    809: 
                    810:        buf[8] = buf[0];
                    811:        buf[9] = buf[1];
                    812:        domakekey(buf);
                    813: 
                    814:        seed = 123;
                    815:        for (i=0; i<13; i++)
                    816:                seed = seed*buf[i] + i;
                    817:        for(i=0;i<256;i++){
                    818:                t1[i] = i;
                    819:                t3[i] = 0;
                    820:        }
                    821:        for(i=0; i<256; i++) {
                    822:                seed = 5*seed + buf[i%13];
                    823:                random = seed % 65521;
                    824:                k = 256-1 - i;
                    825:                ic = (random&0377) % (k+1);
                    826:                random >>= 8;
                    827:                temp = t1[k];
                    828:                t1[k] = t1[ic];
                    829:                t1[ic] = temp;
                    830:                if(t3[k]!=0) continue;
                    831:                ic = (random&0377) % k;
                    832:                while(t3[ic]!=0) ic = (ic+1) % k;
                    833:                t3[k] = ic;
                    834:                t3[ic] = k;
                    835:        }
                    836:        for(i=0; i<256; i++)
                    837:                t2[t1[i]&0377] = i;
                    838:        return(1);
                    839: }
                    840: 
                    841: /*
                    842:  * domakekey: the following is the major nonportable part of the encryption
                    843:  * mechanism. A 10 character key is supplied in buffer.
                    844:  * This string is fed to makekey (an external program) which
                    845:  * responds with a 13 character result. This result is placed
                    846:  * in buffer.
                    847:  */
                    848: domakekey(buffer)
                    849: char *buffer;
                    850: {
                    851:        int pf[2];
                    852: 
                    853:        if (pipe(pf)<0)
                    854:                pf[0] = pf[1] = -1;
                    855:        if (fork()==0) {
                    856:                close(0);
                    857:                close(1);
                    858:                dup(pf[0]);
                    859:                dup(pf[1]);
                    860:                execl("/usr/lib/makekey", "-", 0);
                    861:                execl("/lib/makekey", "-", 0);
                    862:                ex_exit(1);
                    863:        }
                    864:        write(pf[1], buffer, 10);
                    865:        if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13)
                    866:                error("crypt: cannot generate key");
                    867:        close(pf[0]);
                    868:        close(pf[1]);
                    869:        /* end of nonportable part */
                    870: }
                    871: #endif

unix.superglobalmegacorp.com

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