BSD 4 release
[unix-history] / usr / src / cmd / ex / ex_temp.c
index e8f8780..c33225d 100644 (file)
@@ -1,4 +1,5 @@
-/* Copyright (c) 1979 Regents of the University of California */
+/* Copyright (c) 1980 Regents of the University of California */
+static char *sccsid = "@(#)ex_temp.c   6.2 10/23/80";
 #include "ex.h"
 #include "ex_temp.h"
 #include "ex_vis.h"
 #include "ex.h"
 #include "ex_temp.h"
 #include "ex_vis.h"
@@ -57,6 +58,12 @@ dumbness:
        tfile = creat(tfname, 0600);
        if (tfile < 0)
                goto dumbness;
        tfile = creat(tfname, 0600);
        if (tfile < 0)
                goto dumbness;
+#ifdef VMUNIX
+       {
+               extern stilinc;         /* see below */
+               stilinc = 0;
+       }
+#endif
        havetmp = 1;
        close(tfile);
        tfile = open(tfname, 2);
        havetmp = 1;
        close(tfile);
        tfile = open(tfname, 2);
@@ -137,6 +144,8 @@ getblock(atl, iof)
        int iof;
 {
        register int bno, off;
        int iof;
 {
        register int bno, off;
+        register char *p1, *p2;
+        register int n;
        
        bno = (atl >> OFFBTS) & BLKMSK;
        off = (atl << SHFT) & LBTMSK;
        
        bno = (atl >> OFFBTS) & BLKMSK;
        off = (atl << SHFT) & LBTMSK;
@@ -157,39 +166,114 @@ getblock(atl, iof)
                return (obuff + off);
        if (iof == READ) {
                if (hitin2 == 0) {
                return (obuff + off);
        if (iof == READ) {
                if (hitin2 == 0) {
-                       if (ichang2)
+                       if (ichang2) {
+#ifdef CRYPT
+                               if(xtflag)
+                                       crblock(tperm, ibuff2, CRSIZE, (long)0);
+#endif
                                blkio(iblock2, ibuff2, write);
                                blkio(iblock2, ibuff2, write);
+                       }
                        ichang2 = 0;
                        iblock2 = bno;
                        blkio(bno, ibuff2, read);
                        ichang2 = 0;
                        iblock2 = bno;
                        blkio(bno, ibuff2, read);
+#ifdef CRYPT
+                       if(xtflag)
+                               crblock(tperm, ibuff2, CRSIZE, (long)0);
+#endif
                        hitin2 = 1;
                        return (ibuff2 + off);
                }
                hitin2 = 0;
                        hitin2 = 1;
                        return (ibuff2 + off);
                }
                hitin2 = 0;
-               if (ichanged)
+               if (ichanged) {
+#ifdef CRYPT
+                       if(xtflag)
+                               crblock(tperm, ibuff, CRSIZE, (long)0);
+#endif
                        blkio(iblock, ibuff, write);
                        blkio(iblock, ibuff, write);
+               }
                ichanged = 0;
                iblock = bno;
                blkio(bno, ibuff, read);
                ichanged = 0;
                iblock = bno;
                blkio(bno, ibuff, read);
+#ifdef CRYPT
+               if(xtflag)
+                       crblock(tperm, ibuff, CRSIZE, (long)0);
+#endif
                return (ibuff + off);
        }
                return (ibuff + off);
        }
-       if (oblock >= 0)
-               blkio(oblock, obuff, write);
+       if (oblock >= 0) {
+#ifdef CRYPT
+               if(xtflag) {
+                       /*
+                        * Encrypt block before writing, so some devious
+                        * person can't look at temp file while editing.
+                        */
+                       p1 = obuff;
+                       p2 = crbuf;
+                       n = CRSIZE;
+                       while(n--)
+                               *p2++ = *p1++;
+                       crblock(tperm, crbuf, CRSIZE, (long)0);
+                       blkio(oblock, crbuf, write);
+               } else
+#endif
+                       blkio(oblock, obuff, write);
+       }
        oblock = bno;
        return (obuff + off);
 }
 
        oblock = bno;
        return (obuff + off);
 }
 
+#ifdef VMUNIX
+#define        INCORB  64
+char   incorb[INCORB+1][BUFSIZ];
+#define        pagrnd(a)       ((char *)(((int)a)&~(BUFSIZ-1)))
+int    stilinc;        /* up to here not written yet */
+#endif
+
 blkio(b, buf, iofcn)
        short b;
        char *buf;
        int (*iofcn)();
 {
 
 blkio(b, buf, iofcn)
        short b;
        char *buf;
        int (*iofcn)();
 {
 
+#ifdef VMUNIX
+       if (b < INCORB) {
+               if (iofcn == read) {
+                       bcopy(pagrnd(incorb[b+1]), buf, BUFSIZ);
+                       return;
+               }
+               bcopy(buf, pagrnd(incorb[b+1]), BUFSIZ);
+               if (laste) {
+                       if (b >= stilinc)
+                               stilinc = b + 1;
+                       return;
+               }
+       } else if (stilinc)
+               tflush();
+#endif
        lseek(tfile, (long) (unsigned) b * BUFSIZ, 0);
        if ((*iofcn)(tfile, buf, BUFSIZ) != BUFSIZ)
                filioerr(tfname);
 }
 
        lseek(tfile, (long) (unsigned) b * BUFSIZ, 0);
        if ((*iofcn)(tfile, buf, BUFSIZ) != BUFSIZ)
                filioerr(tfname);
 }
 
+#ifdef VMUNIX
+tlaste()
+{
+
+       if (stilinc)
+               dirtcnt = 0;
+}
+
+tflush()
+{
+       int i = stilinc;
+       
+       stilinc = 0;
+       lseek(tfile, (long) 0, 0);
+       if (write(tfile, pagrnd(incorb[1]), i * BUFSIZ) != (i * BUFSIZ))
+               filioerr(tfname);
+}
+#endif
+
 /*
  * Synchronize the state of the temporary file in case
  * a crash occurs.
 /*
  * Synchronize the state of the temporary file in case
  * a crash occurs.
@@ -200,6 +284,10 @@ synctmp()
        register line *a;
        register short *bp;
 
        register line *a;
        register short *bp;
 
+#ifdef VMUNIX
+       if (stilinc)
+               return;
+#endif
        if (dol == zero)
                return;
        if (ichanged)
        if (dol == zero)
                return;
        if (ichanged)
@@ -217,6 +305,8 @@ synctmp()
                if (*bp < 0) {
                        tline = (tline + OFFMSK) &~ OFFMSK;
                        *bp = ((tline >> OFFBTS) & BLKMSK);
                if (*bp < 0) {
                        tline = (tline + OFFMSK) &~ OFFMSK;
                        *bp = ((tline >> OFFBTS) & BLKMSK);
+                       if (*bp > NMBLKS)
+                               error(" Tmp file too large");
                        tline += INCRMT;
                        oblock = *bp + 1;
                        bp[1] = -1;
                        tline += INCRMT;
                        oblock = *bp + 1;
                        bp[1] = -1;
@@ -242,6 +332,10 @@ TSYNC()
 {
 
        if (dirtcnt > 12) {
 {
 
        if (dirtcnt > 12) {
+#ifdef VMUNIX
+               if (stilinc)
+                       tflush();
+#endif
                dirtcnt = 0;
                synctmp();
        }
                dirtcnt = 0;
                synctmp();
        }
@@ -275,7 +369,11 @@ struct     rbuf {
        short   rb_next;
        char    rb_text[BUFSIZ - 2 * sizeof (short)];
 } *rbuf;
        short   rb_next;
        char    rb_text[BUFSIZ - 2 * sizeof (short)];
 } *rbuf;
+#ifdef VMUNIX
+short  rused[256];
+#else
 short  rused[32];
 short  rused[32];
+#endif
 short  rnleft;
 short  rblock;
 short  rnext;
 short  rnleft;
 short  rblock;
 short  rnext;
@@ -396,17 +494,20 @@ putreg(c)
                error("Nothing in register %c", c);
        }
        if (inopen && partreg(c)) {
                error("Nothing in register %c", c);
        }
        if (inopen && partreg(c)) {
+               if (!FIXUNDO) {
+                       splitw++; vclean(); vgoto(WECHO, 0); vreg = -1;
+                       error("Can't put partial line inside macro");
+               }
                squish();
                addr1 = addr2 = dol;
        }
                squish();
                addr1 = addr2 = dol;
        }
-       ignore(append(getREG, addr2));
+       cnt = append(getREG, addr2);
        if (inopen && partreg(c)) {
                unddol = dol;
                dol = odol;
                dot = odot;
                pragged(0);
        }
        if (inopen && partreg(c)) {
                unddol = dol;
                dol = odol;
                dot = odot;
                pragged(0);
        }
-       cnt = undap2 - undap1;
        killcnt(cnt);
        notecnt = cnt;
 }
        killcnt(cnt);
        notecnt = cnt;
 }
@@ -458,6 +559,7 @@ YANKreg(c)
        struct rbuf arbuf;
        register line *addr;
        register struct strreg *sp;
        struct rbuf arbuf;
        register line *addr;
        register struct strreg *sp;
+       char savelb[LBSIZE];
 
        if (isdigit(c))
                kshift();
 
        if (isdigit(c))
                kshift();
@@ -474,6 +576,7 @@ YANKreg(c)
                rblock = 0;
                rnleft = 0;
        }
                rblock = 0;
                rnleft = 0;
        }
+       CP(savelb,linebuf);
        for (addr = addr1; addr <= addr2; addr++) {
                getline(*addr);
                if (sp->rg_flags) {
        for (addr = addr1; addr <= addr2; addr++) {
                getline(*addr);
                if (sp->rg_flags) {
@@ -486,6 +589,7 @@ YANKreg(c)
        }
        rbflush();
        killed();
        }
        rbflush();
        killed();
+       CP(linebuf,savelb);
 }
 
 kshift()
 }
 
 kshift()
@@ -566,3 +670,149 @@ int buflen;
        *p = '\0';
        getDOT();
 }
        *p = '\0';
        getDOT();
 }
+
+/*
+ * Encryption routines.  These are essentially unmodified from ed.
+ */
+
+#ifdef CRYPT
+/*
+ * crblock: encrypt/decrypt a block of text.
+ * buf is the buffer through which the text is both input and
+ * output. nchar is the size of the buffer. permp is a work
+ * buffer, and startn is the beginning of a sequence.
+ */
+crblock(permp, buf, nchar, startn)
+char *permp;
+char *buf;
+int nchar;
+long startn;
+{
+       register char *p1;
+       int n1;
+       int n2;
+       register char *t1, *t2, *t3;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+
+       n1 = startn&0377;
+       n2 = (startn>>8)&0377;
+       p1 = buf;
+       while(nchar--) {
+               *p1 = t2[(t3[(t1[(*p1+n1)&0377]+n2)&0377]-n2)&0377]-n1;
+               n1++;
+               if(n1==256){
+                       n1 = 0;
+                       n2++;
+                       if(n2==256) n2 = 0;
+               }
+               p1++;
+       }
+}
+
+/*
+ * makekey: initialize buffers based on user key a.
+ */
+makekey(a, b)
+char *a, *b;
+{
+       register int i;
+       long t;
+       char temp[KSIZE + 1];
+
+       for(i = 0; i < KSIZE; i++)
+               temp[i] = *a++;
+       time(&t);
+       t += getpid();
+       for(i = 0; i < 4; i++)
+               temp[i] ^= (t>>(8*i))&0377;
+       crinit(temp, b);
+}
+
+/*
+ * crinit: besides initializing the encryption machine, this routine
+ * returns 0 if the key is null, and 1 if it is non-null.
+ */
+crinit(keyp, permp)
+char    *keyp, *permp;
+{
+       register char *t1, *t2, *t3;
+       register i;
+       int ic, k, temp;
+       unsigned random;
+       char buf[13];
+       long seed;
+
+       t1 = permp;
+       t2 = &permp[256];
+       t3 = &permp[512];
+       if(*keyp == 0)
+               return(0);
+       strncpy(buf, keyp, 8);
+       while (*keyp)
+               *keyp++ = '\0';
+
+       buf[8] = buf[0];
+       buf[9] = buf[1];
+       domakekey(buf);
+
+       seed = 123;
+       for (i=0; i<13; i++)
+               seed = seed*buf[i] + i;
+       for(i=0;i<256;i++){
+               t1[i] = i;
+               t3[i] = 0;
+       }
+       for(i=0; i<256; i++) {
+               seed = 5*seed + buf[i%13];
+               random = seed % 65521;
+               k = 256-1 - i;
+               ic = (random&0377) % (k+1);
+               random >>= 8;
+               temp = t1[k];
+               t1[k] = t1[ic];
+               t1[ic] = temp;
+               if(t3[k]!=0) continue;
+               ic = (random&0377) % k;
+               while(t3[ic]!=0) ic = (ic+1) % k;
+               t3[k] = ic;
+               t3[ic] = k;
+       }
+       for(i=0; i<256; i++)
+               t2[t1[i]&0377] = i;
+       return(1);
+}
+
+/*
+ * domakekey: the following is the major nonportable part of the encryption
+ * mechanism. A 10 character key is supplied in buffer.
+ * This string is fed to makekey (an external program) which
+ * responds with a 13 character result. This result is placed
+ * in buffer.
+ */
+domakekey(buffer)
+char *buffer;
+{
+       int pf[2];
+
+       if (pipe(pf)<0)
+               pf[0] = pf[1] = -1;
+       if (fork()==0) {
+               close(0);
+               close(1);
+               dup(pf[0]);
+               dup(pf[1]);
+               execl("/usr/lib/makekey", "-", 0);
+               execl("/lib/makekey", "-", 0);
+               exit(1);
+       }
+       write(pf[1], buffer, 10);
+       if (wait((int *)NULL)==-1 || read(pf[0], buffer, 13)!=13)
+               error("crypt: cannot generate key");
+       close(pf[0]);
+       close(pf[1]);
+       /* end of nonportable part */
+}
+#endif