Annotation of researchv10no/cmd/ex/OLDex_temp.c, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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