home *** CD-ROM | disk | FTP | other *** search
/ minnie.tuhs.org / unixen.tar / unixen / PDP-11 / Trees / V7 / usr / src / cmd / ed.c < prev    next >
Encoding:
C/C++ Source or Header  |  1979-01-10  |  24.3 KB  |  1,763 lines

  1. /*
  2.  * Editor
  3.  */
  4.  
  5. #include <signal.h>
  6. #include <sgtty.h>
  7. #include <setjmp.h>
  8. #define    NULL    0
  9. #define    FNSIZE    64
  10. #define    LBSIZE    512
  11. #define    ESIZE    128
  12. #define    GBSIZE    256
  13. #define    NBRA    5
  14. #define    EOF    -1
  15. #define    KSIZE    9
  16.  
  17. #define    CBRA    1
  18. #define    CCHR    2
  19. #define    CDOT    4
  20. #define    CCL    6
  21. #define    NCCL    8
  22. #define    CDOL    10
  23. #define    CEOF    11
  24. #define    CKET    12
  25. #define    CBACK    14
  26.  
  27. #define    STAR    01
  28.  
  29. char    Q[]    = "";
  30. char    T[]    = "TMP";
  31. #define    READ    0
  32. #define    WRITE    1
  33.  
  34. int    peekc;
  35. int    lastc;
  36. char    savedfile[FNSIZE];
  37. char    file[FNSIZE];
  38. char    linebuf[LBSIZE];
  39. char    rhsbuf[LBSIZE/2];
  40. char    expbuf[ESIZE+4];
  41. int    circfl;
  42. int    *zero;
  43. int    *dot;
  44. int    *dol;
  45. int    *addr1;
  46. int    *addr2;
  47. char    genbuf[LBSIZE];
  48. long    count;
  49. char    *nextip;
  50. char    *linebp;
  51. int    ninbuf;
  52. int    io;
  53. int    pflag;
  54. long    lseek();
  55. int    (*oldhup)();
  56. int    (*oldquit)();
  57. int    vflag    = 1;
  58. int    xflag;
  59. int    xtflag;
  60. int    kflag;
  61. char    key[KSIZE + 1];
  62. char    crbuf[512];
  63. char    perm[768];
  64. char    tperm[768];
  65. int    listf;
  66. int    col;
  67. char    *globp;
  68. int    tfile    = -1;
  69. int    tline;
  70. char    *tfname;
  71. char    *loc1;
  72. char    *loc2;
  73. char    *locs;
  74. char    ibuff[512];
  75. int    iblock    = -1;
  76. char    obuff[512];
  77. int    oblock    = -1;
  78. int    ichanged;
  79. int    nleft;
  80. char    WRERR[]    = "WRITE ERROR";
  81. int    names[26];
  82. int    anymarks;
  83. char    *braslist[NBRA];
  84. char    *braelist[NBRA];
  85. int    nbra;
  86. int    subnewa;
  87. int    subolda;
  88. int    fchange;
  89. int    wrapp;
  90. unsigned nlall = 128;
  91.  
  92. int    *address();
  93. char    *getline();
  94. char    *getblock();
  95. char    *place();
  96. char    *mktemp();
  97. char    *malloc();
  98. char    *realloc();
  99. jmp_buf    savej;
  100.  
  101. main(argc, argv)
  102. char **argv;
  103. {
  104.     register char *p1, *p2;
  105.     extern int onintr(), quit(), onhup();
  106.     int (*oldintr)();
  107.  
  108.     oldquit = signal(SIGQUIT, SIG_IGN);
  109.     oldhup = signal(SIGHUP, SIG_IGN);
  110.     oldintr = signal(SIGINT, SIG_IGN);
  111.     if ((int)signal(SIGTERM, SIG_IGN) == 0)
  112.         signal(SIGTERM, quit);
  113.     argv++;
  114.     while (argc > 1 && **argv=='-') {
  115.         switch((*argv)[1]) {
  116.  
  117.         case '\0':
  118.             vflag = 0;
  119.             break;
  120.  
  121.         case 'q':
  122.             signal(SIGQUIT, SIG_DFL);
  123.             vflag = 1;
  124.             break;
  125.  
  126.         case 'x':
  127.             xflag = 1;
  128.             break;
  129.         }
  130.         argv++;
  131.         argc--;
  132.     }
  133.     if(xflag){
  134.         getkey();
  135.         kflag = crinit(key, perm);
  136.     }
  137.  
  138.     if (argc>1) {
  139.         p1 = *argv;
  140.         p2 = savedfile;
  141.         while (*p2++ = *p1++)
  142.             ;
  143.         globp = "r";
  144.     }
  145.     zero = (int *)malloc(nlall*sizeof(int));
  146.     tfname = mktemp("/tmp/eXXXXX");
  147.     init();
  148.     if (((int)oldintr&01) == 0)
  149.         signal(SIGINT, onintr);
  150.     if (((int)oldhup&01) == 0)
  151.         signal(SIGHUP, onhup);
  152.     setjmp(savej);
  153.     commands();
  154.     quit();
  155. }
  156.  
  157. commands()
  158. {
  159.     int getfile(), gettty();
  160.     register *a1, c;
  161.  
  162.     for (;;) {
  163.     if (pflag) {
  164.         pflag = 0;
  165.         addr1 = addr2 = dot;
  166.         goto print;
  167.     }
  168.     addr1 = 0;
  169.     addr2 = 0;
  170.     do {
  171.         addr1 = addr2;
  172.         if ((a1 = address())==0) {
  173.             c = getchr();
  174.             break;
  175.         }
  176.         addr2 = a1;
  177.         if ((c=getchr()) == ';') {
  178.             c = ',';
  179.             dot = a1;
  180.         }
  181.     } while (c==',');
  182.     if (addr1==0)
  183.         addr1 = addr2;
  184.     switch(c) {
  185.  
  186.     case 'a':
  187.         setdot();
  188.         newline();
  189.         append(gettty, addr2);
  190.         continue;
  191.  
  192.     case 'c':
  193.         delete();
  194.         append(gettty, addr1-1);
  195.         continue;
  196.  
  197.     case 'd':
  198.         delete();
  199.         continue;
  200.  
  201.     case 'E':
  202.         fchange = 0;
  203.         c = 'e';
  204.     case 'e':
  205.         setnoaddr();
  206.         if (vflag && fchange) {
  207.             fchange = 0;
  208.             error(Q);
  209.         }
  210.         filename(c);
  211.         init();
  212.         addr2 = zero;
  213.         goto caseread;
  214.  
  215.     case 'f':
  216.         setnoaddr();
  217.         filename(c);
  218.         puts(savedfile);
  219.         continue;
  220.  
  221.     case 'g':
  222.         global(1);
  223.         continue;
  224.  
  225.     case 'i':
  226.         setdot();
  227.         nonzero();
  228.         newline();
  229.         append(gettty, addr2-1);
  230.         continue;
  231.  
  232.  
  233.     case 'j':
  234.         if (addr2==0) {
  235.             addr1 = dot;
  236.             addr2 = dot+1;
  237.         }
  238.         setdot();
  239.         newline();
  240.         nonzero();
  241.         join();
  242.         continue;
  243.  
  244.     case 'k':
  245.         if ((c = getchr()) < 'a' || c > 'z')
  246.             error(Q);
  247.         newline();
  248.         setdot();
  249.         nonzero();
  250.         names[c-'a'] = *addr2 & ~01;
  251.         anymarks |= 01;
  252.         continue;
  253.  
  254.     case 'm':
  255.         move(0);
  256.         continue;
  257.  
  258.     case '\n':
  259.         if (addr2==0)
  260.             addr2 = dot+1;
  261.         addr1 = addr2;
  262.         goto print;
  263.  
  264.     case 'l':
  265.         listf++;
  266.     case 'p':
  267.     case 'P':
  268.         newline();
  269.     print:
  270.         setdot();
  271.         nonzero();
  272.         a1 = addr1;
  273.         do {
  274.             puts(getline(*a1++));
  275.         } while (a1 <= addr2);
  276.         dot = addr2;
  277.         listf = 0;
  278.         continue;
  279.  
  280.     case 'Q':
  281.         fchange = 0;
  282.     case 'q':
  283.         setnoaddr();
  284.         newline();
  285.         quit();
  286.  
  287.     case 'r':
  288.         filename(c);
  289.     caseread:
  290.         if ((io = open(file, 0)) < 0) {
  291.             lastc = '\n';
  292.             error(file);
  293.         }
  294.         setall();
  295.         ninbuf = 0;
  296.         c = zero != dol;
  297.         append(getfile, addr2);
  298.         exfile();
  299.         fchange = c;
  300.         continue;
  301.  
  302.     case 's':
  303.         setdot();
  304.         nonzero();
  305.         substitute(globp!=0);
  306.         continue;
  307.  
  308.     case 't':
  309.         move(1);
  310.         continue;
  311.  
  312.     case 'u':
  313.         setdot();
  314.         nonzero();
  315.         newline();
  316.         if ((*addr2&~01) != subnewa)
  317.             error(Q);
  318.         *addr2 = subolda;
  319.         dot = addr2;
  320.         continue;
  321.  
  322.     case 'v':
  323.         global(0);
  324.         continue;
  325.  
  326.     case 'W':
  327.         wrapp++;
  328.     case 'w':
  329.         setall();
  330.         nonzero();
  331.         filename(c);
  332.         if(!wrapp ||
  333.           ((io = open(file,1)) == -1) ||
  334.           ((lseek(io, 0L, 2)) == -1))
  335.             if ((io = creat(file, 0666)) < 0)
  336.                 error(file);
  337.         wrapp = 0;
  338.         putfile();
  339.         exfile();
  340.         if (addr1==zero+1 && addr2==dol)
  341.             fchange = 0;
  342.         continue;
  343.  
  344.     case 'x':
  345.         setnoaddr();
  346.         newline();
  347.         xflag = 1;
  348.         puts("Entering encrypting mode!");
  349.         getkey();
  350.         kflag = crinit(key, perm);
  351.         continue;
  352.  
  353.  
  354.     case '=':
  355.         setall();
  356.         newline();
  357.         count = (addr2-zero)&077777;
  358.         putd();
  359.         putchr('\n');
  360.         continue;
  361.  
  362.     case '!':
  363.         callunix();
  364.         continue;
  365.  
  366.     case EOF:
  367.         return;
  368.  
  369.     }
  370.     error(Q);
  371.     }
  372. }
  373.  
  374. int *
  375. address()
  376. {
  377.     register *a1, minus, c;
  378.     int n, relerr;
  379.  
  380.     minus = 0;
  381.     a1 = 0;
  382.     for (;;) {
  383.         c = getchr();
  384.         if ('0'<=c && c<='9') {
  385.             n = 0;
  386.             do {
  387.                 n *= 10;
  388.                 n += c - '0';
  389.             } while ((c = getchr())>='0' && c<='9');
  390.             peekc = c;
  391.             if (a1==0)
  392.                 a1 = zero;
  393.             if (minus<0)
  394.                 n = -n;
  395.             a1 += n;
  396.             minus = 0;
  397.             continue;
  398.         }
  399.         relerr = 0;
  400.         if (a1 || minus)
  401.             relerr++;
  402.         switch(c) {
  403.         case ' ':
  404.         case '\t':
  405.             continue;
  406.     
  407.         case '+':
  408.             minus++;
  409.             if (a1==0)
  410.                 a1 = dot;
  411.             continue;
  412.  
  413.         case '-':
  414.         case '^':
  415.             minus--;
  416.             if (a1==0)
  417.                 a1 = dot;
  418.             continue;
  419.     
  420.         case '?':
  421.         case '/':
  422.             compile(c);
  423.             a1 = dot;
  424.             for (;;) {
  425.                 if (c=='/') {
  426.                     a1++;
  427.                     if (a1 > dol)
  428.                         a1 = zero;
  429.                 } else {
  430.                     a1--;
  431.                     if (a1 < zero)
  432.                         a1 = dol;
  433.                 }
  434.                 if (execute(0, a1))
  435.                     break;
  436.                 if (a1==dot)
  437.                     error(Q);
  438.             }
  439.             break;
  440.     
  441.         case '$':
  442.             a1 = dol;
  443.             break;
  444.     
  445.         case '.':
  446.             a1 = dot;
  447.             break;
  448.  
  449.         case '\'':
  450.             if ((c = getchr()) < 'a' || c > 'z')
  451.                 error(Q);
  452.             for (a1=zero; a1<=dol; a1++)
  453.                 if (names[c-'a'] == (*a1 & ~01))
  454.                     break;
  455.             break;
  456.     
  457.         default:
  458.             peekc = c;
  459.             if (a1==0)
  460.                 return(0);
  461.             a1 += minus;
  462.             if (a1<zero || a1>dol)
  463.                 error(Q);
  464.             return(a1);
  465.         }
  466.         if (relerr)
  467.             error(Q);
  468.     }
  469. }
  470.  
  471. setdot()
  472. {
  473.     if (addr2 == 0)
  474.         addr1 = addr2 = dot;
  475.     if (addr1 > addr2)
  476.         error(Q);
  477. }
  478.  
  479. setall()
  480. {
  481.     if (addr2==0) {
  482.         addr1 = zero+1;
  483.         addr2 = dol;
  484.         if (dol==zero)
  485.             addr1 = zero;
  486.     }
  487.     setdot();
  488. }
  489.  
  490. setnoaddr()
  491. {
  492.     if (addr2)
  493.         error(Q);
  494. }
  495.  
  496. nonzero()
  497. {
  498.     if (addr1<=zero || addr2>dol)
  499.         error(Q);
  500. }
  501.  
  502. newline()
  503. {
  504.     register c;
  505.  
  506.     if ((c = getchr()) == '\n')
  507.         return;
  508.     if (c=='p' || c=='l') {
  509.         pflag++;
  510.         if (c=='l')
  511.             listf++;
  512.         if (getchr() == '\n')
  513.             return;
  514.     }
  515.     error(Q);
  516. }
  517.  
  518. filename(comm)
  519. {
  520.     register char *p1, *p2;
  521.     register c;
  522.  
  523.     count = 0;
  524.     c = getchr();
  525.     if (c=='\n' || c==EOF) {
  526.         p1 = savedfile;
  527.         if (*p1==0 && comm!='f')
  528.             error(Q);
  529.         p2 = file;
  530.         while (*p2++ = *p1++)
  531.             ;
  532.         return;
  533.     }
  534.     if (c!=' ')
  535.         error(Q);
  536.     while ((c = getchr()) == ' ')
  537.         ;
  538.     if (c=='\n')
  539.         error(Q);
  540.     p1 = file;
  541.     do {
  542.         *p1++ = c;
  543.         if (c==' ' || c==EOF)
  544.             error(Q);
  545.     } while ((c = getchr()) != '\n');
  546.     *p1++ = 0;
  547.     if (savedfile[0]==0 || comm=='e' || comm=='f') {
  548.         p1 = savedfile;
  549.         p2 = file;
  550.         while (*p1++ = *p2++)
  551.             ;
  552.     }
  553. }
  554.  
  555. exfile()
  556. {
  557.     close(io);
  558.     io = -1;
  559.     if (vflag) {
  560.         putd();
  561.         putchr('\n');
  562.     }
  563. }
  564.  
  565. onintr()
  566. {
  567.     signal(SIGINT, onintr);
  568.     putchr('\n');
  569.     lastc = '\n';
  570.     error(Q);
  571. }
  572.  
  573. onhup()
  574. {
  575.     signal(SIGINT, SIG_IGN);
  576.     signal(SIGHUP, SIG_IGN);
  577.     if (dol > zero) {
  578.         addr1 = zero+1;
  579.         addr2 = dol;
  580.         io = creat("ed.hup", 0666);
  581.         if (io > 0)
  582.             putfile();
  583.     }
  584.     fchange = 0;
  585.     quit();
  586. }
  587.  
  588. error(s)
  589. char *s;
  590. {
  591.     register c;
  592.  
  593.     wrapp = 0;
  594.     listf = 0;
  595.     putchr('?');
  596.     puts(s);
  597.     count = 0;
  598.     lseek(0, (long)0, 2);
  599.     pflag = 0;
  600.     if (globp)
  601.         lastc = '\n';
  602.     globp = 0;
  603.     peekc = lastc;
  604.     if(lastc)
  605.         while ((c = getchr()) != '\n' && c != EOF)
  606.             ;
  607.     if (io > 0) {
  608.         close(io);
  609.         io = -1;
  610.     }
  611.     longjmp(savej, 1);
  612. }
  613.  
  614. getchr()
  615. {
  616.     char c;
  617.     if (lastc=peekc) {
  618.         peekc = 0;
  619.         return(lastc);
  620.     }
  621.     if (globp) {
  622.         if ((lastc = *globp++) != 0)
  623.             return(lastc);
  624.         globp = 0;
  625.         return(EOF);
  626.     }
  627.     if (read(0, &c, 1) <= 0)
  628.         return(lastc = EOF);
  629.     lastc = c&0177;
  630.     return(lastc);
  631. }
  632.  
  633. gettty()
  634. {
  635.     register c;
  636.     register char *gf;
  637.     register char *p;
  638.  
  639.     p = linebuf;
  640.     gf = globp;
  641.     while ((c = getchr()) != '\n') {
  642.         if (c==EOF) {
  643.             if (gf)
  644.                 peekc = c;
  645.             return(c);
  646.         }
  647.         if ((c &= 0177) == 0)
  648.             continue;
  649.         *p++ = c;
  650.         if (p >= &linebuf[LBSIZE-2])
  651.             error(Q);
  652.     }
  653.     *p++ = 0;
  654.     if (linebuf[0]=='.' && linebuf[1]==0)
  655.         return(EOF);
  656.     return(0);
  657. }
  658.  
  659. getfile()
  660. {
  661.     register c;
  662.     register char *lp, *fp;
  663.  
  664.     lp = linebuf;
  665.     fp = nextip;
  666.     do {
  667.         if (--ninbuf < 0) {
  668.             if ((ninbuf = read(io, genbuf, LBSIZE)-1) < 0)
  669.                 return(EOF);
  670.             fp = genbuf;
  671.             while(fp < &genbuf[ninbuf]) {
  672.                 if (*fp++ & 0200) {
  673.                     if (kflag)
  674.                         crblock(perm, genbuf, ninbuf+1, count);
  675.                     break;
  676.                 }
  677.             }
  678.             fp = genbuf;
  679.         }
  680.         c = *fp++;
  681.         if (c=='\0')
  682.             continue;
  683.         if (c&0200 || lp >= &linebuf[LBSIZE]) {
  684.             lastc = '\n';
  685.             error(Q);
  686.         }
  687.         *lp++ = c;
  688.         count++;
  689.     } while (c != '\n');
  690.     *--lp = 0;
  691.     nextip = fp;
  692.     return(0);
  693. }
  694.  
  695. putfile()
  696. {
  697.     int *a1, n;
  698.     register char *fp, *lp;
  699.     register nib;
  700.  
  701.     nib = 512;
  702.     fp = genbuf;
  703.     a1 = addr1;
  704.     do {
  705.         lp = getline(*a1++);
  706.         for (;;) {
  707.             if (--nib < 0) {
  708.                 n = fp-genbuf;
  709.                 if(kflag)
  710.                     crblock(perm, genbuf, n, count-n);
  711.                 if(write(io, genbuf, n) != n) {
  712.                     puts(WRERR);
  713.                     error(Q);
  714.                 }
  715.                 nib = 511;
  716.                 fp = genbuf;
  717.             }
  718.             count++;
  719.             if ((*fp++ = *lp++) == 0) {
  720.                 fp[-1] = '\n';
  721.                 break;
  722.             }
  723.         }
  724.     } while (a1 <= addr2);
  725.     n = fp-genbuf;
  726.     if(kflag)
  727.         crblock(perm, genbuf, n, count-n);
  728.     if(write(io, genbuf, n) != n) {
  729.         puts(WRERR);
  730.         error(Q);
  731.     }
  732. }
  733.  
  734. append(f, a)
  735. int *a;
  736. int (*f)();
  737. {
  738.     register *a1, *a2, *rdot;
  739.     int nline, tl;
  740.  
  741.     nline = 0;
  742.     dot = a;
  743.     while ((*f)() == 0) {
  744.         if ((dol-zero)+1 >= nlall) {
  745.             int *ozero = zero;
  746.             nlall += 512;
  747.             free((char *)zero);
  748.             if ((zero = (int *)realloc((char *)zero, nlall*sizeof(int)))==NULL) {
  749.                 lastc = '\n';
  750.                 zero = ozero;
  751.                 error("MEM?");
  752.             }
  753.             dot += zero - ozero;
  754.             dol += zero - ozero;
  755.         }
  756.         tl = putline();
  757.         nline++;
  758.         a1 = ++dol;
  759.         a2 = a1+1;
  760.         rdot = ++dot;
  761.         while (a1 > rdot)
  762.             *--a2 = *--a1;
  763.         *rdot = tl;
  764.     }
  765.     return(nline);
  766. }
  767.  
  768. callunix()
  769. {
  770.     register (*savint)(), pid, rpid;
  771.     int retcode;
  772.  
  773.     setnoaddr();
  774.     if ((pid = fork()) == 0) {
  775.         signal(SIGHUP, oldhup);
  776.         signal(SIGQUIT, oldquit);
  777.         execl("/bin/sh", "sh", "-t", 0);
  778.         exit(0100);
  779.     }
  780.     savint = signal(SIGINT, SIG_IGN);
  781.     while ((rpid = wait(&retcode)) != pid && rpid != -1)
  782.         ;
  783.     signal(SIGINT, savint);
  784.     puts("!");
  785. }
  786.  
  787. quit()
  788. {
  789.     if (vflag && fchange && dol!=zero) {
  790.         fchange = 0;
  791.         error(Q);
  792.     }
  793.     unlink(tfname);
  794.     exit(0);
  795. }
  796.  
  797. delete()
  798. {
  799.     setdot();
  800.     newline();
  801.     nonzero();
  802.     rdelete(addr1, addr2);
  803. }
  804.  
  805. rdelete(ad1, ad2)
  806. int *ad1, *ad2;
  807. {
  808.     register *a1, *a2, *a3;
  809.  
  810.     a1 = ad1;
  811.     a2 = ad2+1;
  812.     a3 = dol;
  813.     dol -= a2 - a1;
  814.     do {
  815.         *a1++ = *a2++;
  816.     } while (a2 <= a3);
  817.     a1 = ad1;
  818.     if (a1 > dol)
  819.         a1 = dol;
  820.     dot = a1;
  821.     fchange = 1;
  822. }
  823.  
  824. gdelete()
  825. {
  826.     register *a1, *a2, *a3;
  827.  
  828.     a3 = dol;
  829.     for (a1=zero+1; (*a1&01)==0; a1++)
  830.         if (a1>=a3)
  831.             return;
  832.     for (a2=a1+1; a2<=a3;) {
  833.         if (*a2&01) {
  834.             a2++;
  835.             dot = a1;
  836.         } else
  837.             *a1++ = *a2++;
  838.     }
  839.     dol = a1-1;
  840.     if (dot>dol)
  841.         dot = dol;
  842.     fchange = 1;
  843. }
  844.  
  845. char *
  846. getline(tl)
  847. {
  848.     register char *bp, *lp;
  849.     register nl;
  850.  
  851.     lp = linebuf;
  852.     bp = getblock(tl, READ);
  853.     nl = nleft;
  854.     tl &= ~0377;
  855.     while (*lp++ = *bp++)
  856.         if (--nl == 0) {
  857.             bp = getblock(tl+=0400, READ);
  858.             nl = nleft;
  859.         }
  860.     return(linebuf);
  861. }
  862.  
  863. putline()
  864. {
  865.     register char *bp, *lp;
  866.     register nl;
  867.     int tl;
  868.  
  869.     fchange = 1;
  870.     lp = linebuf;
  871.     tl = tline;
  872.     bp = getblock(tl, WRITE);
  873.     nl = nleft;
  874.     tl &= ~0377;
  875.     while (*bp = *lp++) {
  876.         if (*bp++ == '\n') {
  877.             *--bp = 0;
  878.             linebp = lp;
  879.             break;
  880.         }
  881.         if (--nl == 0) {
  882.             bp = getblock(tl+=0400, WRITE);
  883.             nl = nleft;
  884.         }
  885.     }
  886.     nl = tline;
  887.     tline += (((lp-linebuf)+03)>>1)&077776;
  888.     return(nl);
  889. }
  890.  
  891. char *
  892. getblock(atl, iof)
  893. {
  894.     extern read(), write();
  895.     register bno, off;
  896.     register char *p1, *p2;
  897.     register int n;
  898.     
  899.     bno = (atl>>8)&0377;
  900.     off = (atl<<1)&0774;
  901.     if (bno >= 255) {
  902.         lastc = '\n';
  903.         error(T);
  904.     }
  905.     nleft = 512 - off;
  906.     if (bno==iblock) {
  907.         ichanged |= iof;
  908.         return(ibuff+off);
  909.     }
  910.     if (bno==oblock)
  911.         return(obuff+off);
  912.     if (iof==READ) {
  913.         if (ichanged) {
  914.             if(xtflag)
  915.                 crblock(tperm, ibuff, 512, (long)0);
  916.             blkio(iblock, ibuff, write);
  917.         }
  918.         ichanged = 0;
  919.         iblock = bno;
  920.         blkio(bno, ibuff, read);
  921.         if(xtflag)
  922.             crblock(tperm, ibuff, 512, (long)0);
  923.         return(ibuff+off);
  924.     }
  925.     if (oblock>=0) {
  926.         if(xtflag) {
  927.             p1 = obuff;
  928.             p2 = crbuf;
  929.             n = 512;
  930.             while(n--)
  931.                 *p2++ = *p1++;
  932.             crblock(tperm, crbuf, 512, (long)0);
  933.             blkio(oblock, crbuf, write);
  934.         } else
  935.             blkio(oblock, obuff, write);
  936.     }
  937.     oblock = bno;
  938.     return(obuff+off);
  939. }
  940.  
  941. blkio(b, buf, iofcn)
  942. char *buf;
  943. int (*iofcn)();
  944. {
  945.     lseek(tfile, (long)b<<9, 0);
  946.     if ((*iofcn)(tfile, buf, 512) != 512) {
  947.         error(T);
  948.     }
  949. }
  950.  
  951. init()
  952. {
  953.     register *markp;
  954.  
  955.     close(tfile);
  956.     tline = 2;
  957.     for (markp = names; markp < &names[26]; )
  958.         *markp++ = 0;
  959.     subnewa = 0;
  960.     anymarks = 0;
  961.     iblock = -1;
  962.     oblock = -1;
  963.     ichanged = 0;
  964.     close(creat(tfname, 0600));
  965.     tfile = open(tfname, 2);
  966.     if(xflag) {
  967.         xtflag = 1;
  968.         makekey(key, tperm);
  969.     }
  970.     dot = dol = zero;
  971. }
  972.  
  973. global(k)
  974. {
  975.     register char *gp;
  976.     register c;
  977.     register int *a1;
  978.     char globuf[GBSIZE];
  979.  
  980.     if (globp)
  981.         error(Q);
  982.     setall();
  983.     nonzero();
  984.     if ((c=getchr())=='\n')
  985.         error(Q);
  986.     compile(c);
  987.     gp = globuf;
  988.     while ((c = getchr()) != '\n') {
  989.         if (c==EOF)
  990.             error(Q);
  991.         if (c=='\\') {
  992.             c = getchr();
  993.             if (c!='\n')
  994.                 *gp++ = '\\';
  995.         }
  996.         *gp++ = c;
  997.         if (gp >= &globuf[GBSIZE-2])
  998.             error(Q);
  999.     }
  1000.     *gp++ = '\n';
  1001.     *gp++ = 0;
  1002.     for (a1=zero; a1<=dol; a1++) {
  1003.         *a1 &= ~01;
  1004.         if (a1>=addr1 && a1<=addr2 && execute(0, a1)==k)
  1005.             *a1 |= 01;
  1006.     }
  1007.     /*
  1008.      * Special case: g/.../d (avoid n^2 algorithm)
  1009.      */
  1010.     if (globuf[0]=='d' && globuf[1]=='\n' && globuf[2]=='\0') {
  1011.         gdelete();
  1012.         return;
  1013.     }
  1014.     for (a1=zero; a1<=dol; a1++) {
  1015.         if (*a1 & 01) {
  1016.             *a1 &= ~01;
  1017.             dot = a1;
  1018.             globp = globuf;
  1019.             commands();
  1020.             a1 = zero;
  1021.         }
  1022.     }
  1023. }
  1024.  
  1025. join()
  1026. {
  1027.     register char *gp, *lp;
  1028.     register *a1;
  1029.  
  1030.     gp = genbuf;
  1031.     for (a1=addr1; a1<=addr2; a1++) {
  1032.         lp = getline(*a1);
  1033.         while (*gp = *lp++)
  1034.             if (gp++ >= &genbuf[LBSIZE-2])
  1035.                 error(Q);
  1036.     }
  1037.     lp = linebuf;
  1038.     gp = genbuf;
  1039.     while (*lp++ = *gp++)
  1040.         ;
  1041.     *addr1 = putline();
  1042.     if (addr1<addr2)
  1043.         rdelete(addr1+1, addr2);
  1044.     dot = addr1;
  1045. }
  1046.  
  1047. substitute(inglob)
  1048. {
  1049.     register *markp, *a1, nl;
  1050.     int gsubf;
  1051.     int getsub();
  1052.  
  1053.     gsubf = compsub();
  1054.     for (a1 = addr1; a1 <= addr2; a1++) {
  1055.         int *ozero;
  1056.         if (execute(0, a1)==0)
  1057.             continue;
  1058.         inglob |= 01;
  1059.         dosub();
  1060.         if (gsubf) {
  1061.             while (*loc2) {
  1062.                 if (execute(1, (int *)0)==0)
  1063.                     break;
  1064.                 dosub();
  1065.             }
  1066.         }
  1067.         subnewa = putline();
  1068.         *a1 &= ~01;
  1069.         if (anymarks) {
  1070.             for (markp = names; markp < &names[26]; markp++)
  1071.                 if (*markp == *a1)
  1072.                     *markp = subnewa;
  1073.         }
  1074.         subolda = *a1;
  1075.         *a1 = subnewa;
  1076.         ozero = zero;
  1077.         nl = append(getsub, a1);
  1078.         nl += zero-ozero;
  1079.         a1 += nl;
  1080.         addr2 += nl;
  1081.     }
  1082.     if (inglob==0)
  1083.         error(Q);
  1084. }
  1085.  
  1086. compsub()
  1087. {
  1088.     register seof, c;
  1089.     register char *p;
  1090.  
  1091.     if ((seof = getchr()) == '\n' || seof == ' ')
  1092.         error(Q);
  1093.     compile(seof);
  1094.     p = rhsbuf;
  1095.     for (;;) {
  1096.         c = getchr();
  1097.         if (c=='\\')
  1098.             c = getchr() | 0200;
  1099.         if (c=='\n') {
  1100.             if (globp)
  1101.                 c |= 0200;
  1102.             else
  1103.                 error(Q);
  1104.         }
  1105.         if (c==seof)
  1106.             break;
  1107.         *p++ = c;
  1108.         if (p >= &rhsbuf[LBSIZE/2])
  1109.             error(Q);
  1110.     }
  1111.     *p++ = 0;
  1112.     if ((peekc = getchr()) == 'g') {
  1113.         peekc = 0;
  1114.         newline();
  1115.         return(1);
  1116.     }
  1117.     newline();
  1118.     return(0);
  1119. }
  1120.  
  1121. getsub()
  1122. {
  1123.     register char *p1, *p2;
  1124.  
  1125.     p1 = linebuf;
  1126.     if ((p2 = linebp) == 0)
  1127.         return(EOF);
  1128.     while (*p1++ = *p2++)
  1129.         ;
  1130.     linebp = 0;
  1131.     return(0);
  1132. }
  1133.  
  1134. dosub()
  1135. {
  1136.     register char *lp, *sp, *rp;
  1137.     int c;
  1138.  
  1139.     lp = linebuf;
  1140.     sp = genbuf;
  1141.     rp = rhsbuf;
  1142.     while (lp < loc1)
  1143.         *sp++ = *lp++;
  1144.     while (c = *rp++&0377) {
  1145.         if (c=='&') {
  1146.             sp = place(sp, loc1, loc2);
  1147.             continue;
  1148.         } else if (c&0200 && (c &= 0177) >='1' && c < nbra+'1') {
  1149.             sp = place(sp, braslist[c-'1'], braelist[c-'1']);
  1150.             continue;
  1151.         }
  1152.         *sp++ = c&0177;
  1153.         if (sp >= &genbuf[LBSIZE])
  1154.             error(Q);
  1155.     }
  1156.     lp = loc2;
  1157.     loc2 = sp - genbuf + linebuf;
  1158.     while (*sp++ = *lp++)
  1159.         if (sp >= &genbuf[LBSIZE])
  1160.             error(Q);
  1161.     lp = linebuf;
  1162.     sp = genbuf;
  1163.     while (*lp++ = *sp++)
  1164.         ;
  1165. }
  1166.  
  1167. char *
  1168. place(sp, l1, l2)
  1169. register char *sp, *l1, *l2;
  1170. {
  1171.  
  1172.     while (l1 < l2) {
  1173.         *sp++ = *l1++;
  1174.         if (sp >= &genbuf[LBSIZE])
  1175.             error(Q);
  1176.     }
  1177.     return(sp);
  1178. }
  1179.  
  1180. move(cflag)
  1181. {
  1182.     register int *adt, *ad1, *ad2;
  1183.     int getcopy();
  1184.  
  1185.     setdot();
  1186.     nonzero();
  1187.     if ((adt = address())==0)
  1188.         error(Q);
  1189.     newline();
  1190.     if (cflag) {
  1191.         int *ozero, delta;
  1192.         ad1 = dol;
  1193.         ozero = zero;
  1194.         append(getcopy, ad1++);
  1195.         ad2 = dol;
  1196.         delta = zero - ozero;
  1197.         ad1 += delta;
  1198.         adt += delta;
  1199.     } else {
  1200.         ad2 = addr2;
  1201.         for (ad1 = addr1; ad1 <= ad2;)
  1202.             *ad1++ &= ~01;
  1203.         ad1 = addr1;
  1204.     }
  1205.     ad2++;
  1206.     if (adt<ad1) {
  1207.         dot = adt + (ad2-ad1);
  1208.         if ((++adt)==ad1)
  1209.             return;
  1210.         reverse(adt, ad1);
  1211.         reverse(ad1, ad2);
  1212.         reverse(adt, ad2);
  1213.     } else if (adt >= ad2) {
  1214.         dot = adt++;
  1215.         reverse(ad1, ad2);
  1216.         reverse(ad2, adt);
  1217.         reverse(ad1, adt);
  1218.     } else
  1219.         error(Q);
  1220.     fchange = 1;
  1221. }
  1222.  
  1223. reverse(a1, a2)
  1224. register int *a1, *a2;
  1225. {
  1226.     register int t;
  1227.  
  1228.     for (;;) {
  1229.         t = *--a2;
  1230.         if (a2 <= a1)
  1231.             return;
  1232.         *a2 = *a1;
  1233.         *a1++ = t;
  1234.     }
  1235. }
  1236.  
  1237. getcopy()
  1238. {
  1239.     if (addr1 > addr2)
  1240.         return(EOF);
  1241.     getline(*addr1++);
  1242.     return(0);
  1243. }
  1244.  
  1245. compile(aeof)
  1246. {
  1247.     register eof, c;
  1248.     register char *ep;
  1249.     char *lastep;
  1250.     char bracket[NBRA], *bracketp;
  1251.     int cclcnt;
  1252.  
  1253.     ep = expbuf;
  1254.     eof = aeof;
  1255.     bracketp = bracket;
  1256.     if ((c = getchr()) == eof) {
  1257.         if (*ep==0)
  1258.             error(Q);
  1259.         return;
  1260.     }
  1261.     circfl = 0;
  1262.     nbra = 0;
  1263.     if (c=='^') {
  1264.         c = getchr();
  1265.         circfl++;
  1266.     }
  1267.     peekc = c;
  1268.     lastep = 0;
  1269.     for (;;) {
  1270.         if (ep >= &expbuf[ESIZE])
  1271.             goto cerror;
  1272.         c = getchr();
  1273.         if (c==eof) {
  1274.             if (bracketp != bracket)
  1275.                 goto cerror;
  1276.             *ep++ = CEOF;
  1277.             return;
  1278.         }
  1279.         if (c!='*')
  1280.             lastep = ep;
  1281.         switch (c) {
  1282.  
  1283.         case '\\':
  1284.             if ((c = getchr())=='(') {
  1285.                 if (nbra >= NBRA)
  1286.                     goto cerror;
  1287.                 *bracketp++ = nbra;
  1288.                 *ep++ = CBRA;
  1289.                 *ep++ = nbra++;
  1290.                 continue;
  1291.             }
  1292.             if (c == ')') {
  1293.                 if (bracketp <= bracket)
  1294.                     goto cerror;
  1295.                 *ep++ = CKET;
  1296.                 *ep++ = *--bracketp;
  1297.                 continue;
  1298.             }
  1299.             if (c>='1' && c<'1'+NBRA) {
  1300.                 *ep++ = CBACK;
  1301.                 *ep++ = c-'1';
  1302.                 continue;
  1303.             }
  1304.             *ep++ = CCHR;
  1305.             if (c=='\n')
  1306.                 goto cerror;
  1307.             *ep++ = c;
  1308.             continue;
  1309.  
  1310.         case '.':
  1311.             *ep++ = CDOT;
  1312.             continue;
  1313.  
  1314.         case '\n':
  1315.             goto cerror;
  1316.  
  1317.         case '*':
  1318.             if (lastep==0 || *lastep==CBRA || *lastep==CKET)
  1319.                 goto defchar;
  1320.             *lastep |= STAR;
  1321.             continue;
  1322.  
  1323.         case '$':
  1324.             if ((peekc=getchr()) != eof)
  1325.                 goto defchar;
  1326.             *ep++ = CDOL;
  1327.             continue;
  1328.  
  1329.         case '[':
  1330.             *ep++ = CCL;
  1331.             *ep++ = 0;
  1332.             cclcnt = 1;
  1333.             if ((c=getchr()) == '^') {
  1334.                 c = getchr();
  1335.                 ep[-2] = NCCL;
  1336.             }
  1337.             do {
  1338.                 if (c=='\n')
  1339.                     goto cerror;
  1340.                 if (c=='-' && ep[-1]!=0) {
  1341.                     if ((c=getchr())==']') {
  1342.                         *ep++ = '-';
  1343.                         cclcnt++;
  1344.                         break;
  1345.                     }
  1346.                     while (ep[-1]<c) {
  1347.                         *ep = ep[-1]+1;
  1348.                         ep++;
  1349.                         cclcnt++;
  1350.                         if (ep>=&expbuf[ESIZE])
  1351.                             goto cerror;
  1352.                     }
  1353.                 }
  1354.                 *ep++ = c;
  1355.                 cclcnt++;
  1356.                 if (ep >= &expbuf[ESIZE])
  1357.                     goto cerror;
  1358.             } while ((c = getchr()) != ']');
  1359.             lastep[1] = cclcnt;
  1360.             continue;
  1361.  
  1362.         defchar:
  1363.         default:
  1364.             *ep++ = CCHR;
  1365.             *ep++ = c;
  1366.         }
  1367.     }
  1368.    cerror:
  1369.     expbuf[0] = 0;
  1370.     nbra = 0;
  1371.     error(Q);
  1372. }
  1373.  
  1374. execute(gf, addr)
  1375. int *addr;
  1376. {
  1377.     register char *p1, *p2, c;
  1378.  
  1379.     for (c=0; c<NBRA; c++) {
  1380.         braslist[c] = 0;
  1381.         braelist[c] = 0;
  1382.     }
  1383.     if (gf) {
  1384.         if (circfl)
  1385.             return(0);
  1386.         p1 = linebuf;
  1387.         p2 = genbuf;
  1388.         while (*p1++ = *p2++)
  1389.             ;
  1390.         locs = p1 = loc2;
  1391.     } else {
  1392.         if (addr==zero)
  1393.             return(0);
  1394.         p1 = getline(*addr);
  1395.         locs = 0;
  1396.     }
  1397.     p2 = expbuf;
  1398.     if (circfl) {
  1399.         loc1 = p1;
  1400.         return(advance(p1, p2));
  1401.     }
  1402.     /* fast check for first character */
  1403.     if (*p2==CCHR) {
  1404.         c = p2[1];
  1405.         do {
  1406.             if (*p1!=c)
  1407.                 continue;
  1408.             if (advance(p1, p2)) {
  1409.                 loc1 = p1;
  1410.                 return(1);
  1411.             }
  1412.         } while (*p1++);
  1413.         return(0);
  1414.     }
  1415.     /* regular algorithm */
  1416.     do {
  1417.         if (advance(p1, p2)) {
  1418.             loc1 = p1;
  1419.             return(1);
  1420.         }
  1421.     } while (*p1++);
  1422.     return(0);
  1423. }
  1424.  
  1425. advance(lp, ep)
  1426. register char *ep, *lp;
  1427. {
  1428.     register char *curlp;
  1429.     int i;
  1430.  
  1431.     for (;;) switch (*ep++) {
  1432.  
  1433.     case CCHR:
  1434.         if (*ep++ == *lp++)
  1435.             continue;
  1436.         return(0);
  1437.  
  1438.     case CDOT:
  1439.         if (*lp++)
  1440.             continue;
  1441.         return(0);
  1442.  
  1443.     case CDOL:
  1444.         if (*lp==0)
  1445.             continue;
  1446.         return(0);
  1447.  
  1448.     case CEOF:
  1449.         loc2 = lp;
  1450.         return(1);
  1451.  
  1452.     case CCL:
  1453.         if (cclass(ep, *lp++, 1)) {
  1454.             ep += *ep;
  1455.             continue;
  1456.         }
  1457.         return(0);
  1458.  
  1459.     case NCCL:
  1460.         if (cclass(ep, *lp++, 0)) {
  1461.             ep += *ep;
  1462.             continue;
  1463.         }
  1464.         return(0);
  1465.  
  1466.     case CBRA:
  1467.         braslist[*ep++] = lp;
  1468.         continue;
  1469.  
  1470.     case CKET:
  1471.         braelist[*ep++] = lp;
  1472.         continue;
  1473.  
  1474.     case CBACK:
  1475.         if (braelist[i = *ep++]==0)
  1476.             error(Q);
  1477.         if (backref(i, lp)) {
  1478.             lp += braelist[i] - braslist[i];
  1479.             continue;
  1480.         }
  1481.         return(0);
  1482.  
  1483.     case CBACK|STAR:
  1484.         if (braelist[i = *ep++] == 0)
  1485.             error(Q);
  1486.         curlp = lp;
  1487.         while (backref(i, lp))
  1488.             lp += braelist[i] - braslist[i];
  1489.         while (lp >= curlp) {
  1490.             if (advance(lp, ep))
  1491.                 return(1);
  1492.             lp -= braelist[i] - braslist[i];
  1493.         }
  1494.         continue;
  1495.  
  1496.     case CDOT|STAR:
  1497.         curlp = lp;
  1498.         while (*lp++)
  1499.             ;
  1500.         goto star;
  1501.  
  1502.     case CCHR|STAR:
  1503.         curlp = lp;
  1504.         while (*lp++ == *ep)
  1505.             ;
  1506.         ep++;
  1507.         goto star;
  1508.  
  1509.     case CCL|STAR:
  1510.     case NCCL|STAR:
  1511.         curlp = lp;
  1512.         while (cclass(ep, *lp++, ep[-1]==(CCL|STAR)))
  1513.             ;
  1514.         ep += *ep;
  1515.         goto star;
  1516.  
  1517.     star:
  1518.         do {
  1519.             lp--;
  1520.             if (lp==locs)
  1521.                 break;
  1522.             if (advance(lp, ep))
  1523.                 return(1);
  1524.         } while (lp > curlp);
  1525.         return(0);
  1526.  
  1527.     default:
  1528.         error(Q);
  1529.     }
  1530. }
  1531.  
  1532. backref(i, lp)
  1533. register i;
  1534. register char *lp;
  1535. {
  1536.     register char *bp;
  1537.  
  1538.     bp = braslist[i];
  1539.     while (*bp++ == *lp++)
  1540.         if (bp >= braelist[i])
  1541.             return(1);
  1542.     return(0);
  1543. }
  1544.  
  1545. cclass(set, c, af)
  1546. register char *set, c;
  1547. {
  1548.     register n;
  1549.  
  1550.     if (c==0)
  1551.         return(0);
  1552.     n = *set++;
  1553.     while (--n)
  1554.         if (*set++ == c)
  1555.             return(af);
  1556.     return(!af);
  1557. }
  1558.  
  1559. putd()
  1560. {
  1561.     register r;
  1562.  
  1563.     r = count%10;
  1564.     count /= 10;
  1565.     if (count)
  1566.         putd();
  1567.     putchr(r + '0');
  1568. }
  1569.  
  1570. puts(sp)
  1571. register char *sp;
  1572. {
  1573.     col = 0;
  1574.     while (*sp)
  1575.         putchr(*sp++);
  1576.     putchr('\n');
  1577. }
  1578.  
  1579. char    line[70];
  1580. char    *linp    = line;
  1581.  
  1582. putchr(ac)
  1583. {
  1584.     register char *lp;
  1585.     register c;
  1586.  
  1587.     lp = linp;
  1588.     c = ac;
  1589.     if (listf) {
  1590.         col++;
  1591.         if (col >= 72) {
  1592.             col = 0;
  1593.             *lp++ = '\\';
  1594.             *lp++ = '\n';
  1595.         }
  1596.         if (c=='\t') {
  1597.             c = '>';
  1598.             goto esc;
  1599.         }
  1600.         if (c=='\b') {
  1601.             c = '<';
  1602.         esc:
  1603.             *lp++ = '-';
  1604.             *lp++ = '\b';
  1605.             *lp++ = c;
  1606.             goto out;
  1607.         }
  1608.         if (c<' ' && c!= '\n') {
  1609.             *lp++ = '\\';
  1610.             *lp++ = (c>>3)+'0';
  1611.             *lp++ = (c&07)+'0';
  1612.             col += 2;
  1613.             goto out;
  1614.         }
  1615.     }
  1616.     *lp++ = c;
  1617. out:
  1618.     if(c == '\n' || lp >= &line[64]) {
  1619.         linp = line;
  1620.         write(1, line, lp-line);
  1621.         return;
  1622.     }
  1623.     linp = lp;
  1624. }
  1625. crblock(permp, buf, nchar, startn)
  1626. char *permp;
  1627. char *buf;
  1628. long startn;
  1629. {
  1630.     register char *p1;
  1631.     int n1;
  1632.     int n2;
  1633.     register char *t1, *t2, *t3;
  1634.  
  1635.     t1 = permp;
  1636.     t2 = &permp[256];
  1637.     t3 = &permp[512];
  1638.  
  1639.     n1 = startn&0377;
  1640.     n2 = (startn>>8)&0377;
  1641.     p1 = buf;
  1642.     while(nchar--) {
  1643.         *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
  1644.         n1++;
  1645.         if(n1==256){
  1646.             n1 = 0;
  1647.             n2++;
  1648.             if(n2==256) n2 = 0;
  1649.         }
  1650.         p1++;
  1651.     }
  1652. }
  1653.  
  1654. getkey()
  1655. {
  1656.     struct sgttyb b;
  1657.     int save;
  1658.     int (*sig)();
  1659.     register char *p;
  1660.     register c;
  1661.  
  1662.     sig = signal(SIGINT, SIG_IGN);
  1663.     if (gtty(0, &b) == -1)
  1664.         error("Input not tty");
  1665.     save = b.sg_flags;
  1666.     b.sg_flags &= ~ECHO;
  1667.     stty(0, &b);
  1668.     puts("Key:");
  1669.     p = key;
  1670.     while(((c=getchr()) != EOF) && (c!='\n')) {
  1671.         if(p < &key[KSIZE])
  1672.             *p++ = c;
  1673.     }
  1674.     *p = 0;
  1675.     b.sg_flags = save;
  1676.     stty(0, &b);
  1677.     signal(SIGINT, sig);
  1678.     return(key[0] != 0);
  1679. }
  1680.  
  1681. /*
  1682.  * Besides initializing the encryption machine, this routine
  1683.  * returns 0 if the key is null, and 1 if it is non-null.
  1684.  */
  1685. crinit(keyp, permp)
  1686. char    *keyp, *permp;
  1687. {
  1688.     register char *t1, *t2, *t3;
  1689.     register i;
  1690.     int ic, k, temp, pf[2];
  1691.     unsigned random;
  1692.     char buf[13];
  1693.     long seed;
  1694.  
  1695.     t1 = permp;
  1696.     t2 = &permp[256];
  1697.     t3 = &permp[512];
  1698.     if(*keyp == 0)
  1699.         return(0);
  1700.     strncpy(buf, keyp, 8);
  1701.     while (*keyp)
  1702.         *keyp++ = '\0';
  1703.     buf[8] = buf[0];
  1704.     buf[9] = buf[1];
  1705.     if (pipe(pf)<0)
  1706.         pf[0] = pf[1] = -1;
  1707.     if (fork()==0) {
  1708.         close(0);
  1709.         close(1);
  1710.         dup(pf[0]);
  1711.         dup(pf[1]);
  1712.         execl("/usr/lib/makekey", "-", 0);
  1713.         execl("/lib/makekey", "-", 0);
  1714.         exit(1);
  1715.     }
  1716.     write(pf[1], buf, 10);
  1717.     if (wait((int *)NULL)==-1 || read(pf[0], buf, 13)!=13)
  1718.         error("crypt: cannot generate key");
  1719.     close(pf[0]);
  1720.     close(pf[1]);
  1721.     seed = 123;
  1722.     for (i=0; i<13; i++)
  1723.         seed = seed*buf[i] + i;
  1724.     for(i=0;i<256;i++){
  1725.         t1[i] = i;
  1726.         t3[i] = 0;
  1727.     }
  1728.     for(i=0; i<256; i++) {
  1729.         seed = 5*seed + buf[i%13];
  1730.         random = seed % 65521;
  1731.         k = 256-1 - i;
  1732.         ic = (random&0377) % (k+1);
  1733.         random >>= 8;
  1734.         temp = t1[k];
  1735.         t1[k] = t1[ic];
  1736.         t1[ic] = temp;
  1737.         if(t3[k]!=0) continue;
  1738.         ic = (random&0377) % k;
  1739.         while(t3[ic]!=0) ic = (ic+1) % k;
  1740.         t3[k] = ic;
  1741.         t3[ic] = k;
  1742.     }
  1743.     for(i=0; i<256; i++)
  1744.         t2[t1[i]&0377] = i;
  1745.     return(1);
  1746. }
  1747.  
  1748. makekey(a, b)
  1749. char *a, *b;
  1750. {
  1751.     register int i;
  1752.     long t;
  1753.     char temp[KSIZE + 1];
  1754.  
  1755.     for(i = 0; i < KSIZE; i++)
  1756.         temp[i] = *a++;
  1757.     time(&t);
  1758.     t += getpid();
  1759.     for(i = 0; i < 4; i++)
  1760.         temp[i] ^= (t>>(8*i))&0377;
  1761.     crinit(temp, b);
  1762. }
  1763.