/* Copyright (c) 1981 Regents of the University of California */
static char *sccsid
= "@(#)ex_temp.c 7.4 %G%";
* Editor temporary file routines.
* Very similar to those of ed, except uses 2 input buffers.
if (tline
== INCRMT
* (HBLKS
+2))
tline
= INCRMT
* (HBLKS
+2);
CP(tfname
, svalue(DIRECTORY
));
if (stat(tfname
, &stbuf
)) {
if ((stbuf
.st_mode
& S_IFMT
) != S_IFDIR
) {
ignore(strcat(tfname
, "/ExXXXXX"));
for (p
= strend(tfname
), i
= 5, j
= getpid(); i
> 0; i
--, j
/= 10)
tfile
= creat(tfname
, 0600);
extern stilinc
; /* see below */
/* brk((char *)fendcore); */
bp
= getblock(tl
+= INCRMT
, READ
);
bp
= getblock(tl
, WRITE
);
bp
= getblock(tl
+= INCRMT
, WRITE
);
tline
+= (((lp
- linebuf
) + BNDRY
- 1) >> SHFT
) & 077776;
bno
= (atl
>> OFFBTS
) & BLKMSK
;
off
= (atl
<< SHFT
) & LBTMSK
;
error(" Tmp file too large");
crblock(tperm
, ibuff2
, CRSIZE
, (long)0);
blkio(iblock2
, ibuff2
, write
);
blkio(bno
, ibuff2
, read
);
crblock(tperm
, ibuff2
, CRSIZE
, (long)0);
crblock(tperm
, ibuff
, CRSIZE
, (long)0);
blkio(iblock
, ibuff
, write
);
crblock(tperm
, ibuff
, CRSIZE
, (long)0);
* Encrypt block before writing, so some devious
* person can't look at temp file while editing.
crblock(tperm
, crbuf
, CRSIZE
, (long)0);
blkio(oblock
, crbuf
, write
);
blkio(oblock
, obuff
, write
);
char incorb
[INCORB
+1][BUFSIZ
];
#define pagrnd(a) ((char *)(((int)a)&~(BUFSIZ-1)))
int stilinc
; /* up to here not written yet */
bcopy(pagrnd(incorb
[b
+1]), buf
, BUFSIZ
);
bcopy(buf
, pagrnd(incorb
[b
+1]), BUFSIZ
);
lseek(tfile
, (long) (unsigned) b
* BUFSIZ
, 0);
if ((*iofcn
)(tfile
, buf
, BUFSIZ
) != BUFSIZ
)
lseek(tfile
, (long) 0, 0);
if (write(tfile
, pagrnd(incorb
[1]), i
* BUFSIZ
) != (i
* BUFSIZ
))
* Synchronize the state of the temporary file in case
blkio(iblock
, ibuff
, write
);
blkio(iblock2
, ibuff2
, write
);
blkio(oblock
, obuff
, write
);
for (a
= zero
, bp
= blocks
; a
<= dol
; a
+= BUFSIZ
/ sizeof *a
, bp
++) {
tline
= (tline
+ OFFMSK
) &~ OFFMSK
;
*bp
= ((tline
>> OFFBTS
) & BLKMSK
);
error(" Tmp file too large");
lseek(tfile
, (long) (unsigned) *bp
* BUFSIZ
, 0);
cnt
= ((dol
- a
) + 2) * sizeof (line
);
if (write(tfile
, (char *) a
, cnt
) != cnt
) {
if (write(tfile
, (char *) &H
, sizeof H
) != sizeof H
)
* This will insure that exrecover gets as much
* back after a crash as is absolutely possible,
* but can result in pregnant pauses between commands
* when the TSYNC call is made, so...
if (dirtcnt
> MAXDIRT
) { /* mjm: 12 --> MAXDIRT */
* These are implemented differently than the main buffer.
* Each named buffer has a chain of blocks in the register file.
* Each block contains roughly 508 chars of text,
* and a previous and next block number. We also have information
* about which blocks came from deletes of multiple partial lines,
* e.g. deleting a sentence or a LISP object.
* We maintain a free map for the temp file. To free the blocks
* in a register we must read the blocks to find how they are chained
* BUG: The default savind of deleted lines in numbered
* buffers may be rather inefficient; it hasn't been profiled.
} strregs
[('z'-'a'+1) + ('9'-'0'+1)], *strp
;
char rb_text
[BUFSIZ
- 2 * sizeof (short)];
} *rbuf
, KILLrbuf
, putrbuf
, YANKrbuf
, regrbuf
;
*(strend(rfname
) - 7) = 'R';
rfile
= creat(rfname
, 0600);
lseek(rfile
, (long) b
* BUFSIZ
, 0);
if ((*iofcn
)(rfile
, rbuf
, BUFSIZ
) != BUFSIZ
)
for (i
= 0; i
< sizeof rused
/ sizeof rused
[0]; i
++) {
m
= (rused
[i
] ^ 0177777) & 0177777;
printf("allocating block %d\n", i
* 16 + j
);
error("Out of register space (ugh)");
return (isdigit(c
) ? &strregs
[('z'-'a'+1)+(c
-'0')] : &strregs
[c
-'a']);
register struct strreg
*sp
;
sp
->rg_first
= sp
->rg_last
= 0;
sp
->rg_flags
= sp
->rg_nleft
= 0;
printf("freeing block %d\n", rblock
);
rused
[rblock
/ 16] &= ~(1 << (rblock
% 16));
struct front
{ short a
; short b
; };
if (read(rfile
, (char *) rbuf
, sizeof (struct front
)) == sizeof (struct front
))
return (sizeof (struct rbuf
));
register line
*odot
= dot
;
register line
*odol
= dol
;
rnext
= mapreg(c
)->rg_first
;
error("Nothing in register %c", c
);
if (inopen
&& partreg(c
)) {
splitw
++; vclean(); vgoto(WECHO
, 0); vreg
= -1;
error("Can't put partial line inside macro");
cnt
= append(getREG
, addr2
);
if (inopen
&& partreg(c
)) {
return (mapreg(c
)->rg_flags
);
register char *lp
= linebuf
;
rnleft
= sizeof rbuf
->rb_text
;
register struct strreg
*sp
;
sp
->rg_flags
= inopen
&& cursor
&& wcursor
;
regio(sp
->rg_last
, read
);
rbufcp
= &rbuf
->rb_text
[sizeof rbuf
->rb_text
- rnleft
];
for (addr
= addr1
; addr
<= addr2
; addr
++) {
for (i
= '8'; i
>= '0'; i
--)
copy(mapreg(i
+1), mapreg(i
), sizeof (struct strreg
));
register char *lp
= linebuf
;
register struct rbuf
*rp
= rbuf
;
rnleft
= sizeof rp
->rb_text
;
register struct strreg
*sp
= strp
;
/* Register c to char buffer buf of size buflen */
rnext
= mapreg(c
)->rg_first
;
error("Nothing in register %c",c
);
error("Register too long@to fit in memory");
* Encryption routines. These are essentially unmodified from ed.
* 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
)
register char *t1
, *t2
, *t3
;
*p1
= t2
[(t3
[(t1
[(*p1
+n1
)&0377]+n2
)&0377]-n2
)&0377]-n1
;
* makekey: initialize buffers based on user key a.
for(i
= 0; i
< KSIZE
; i
++)
temp
[i
] ^= (t
>>(8*i
))&0377;
* crinit: besides initializing the encryption machine, this routine
* returns 0 if the key is null, and 1 if it is non-null.
register char *t1
, *t2
, *t3
;
seed
= 5*seed
+ buf
[i
%13];
ic
= (random
&0377) % (k
+1);
while(t3
[ic
]!=0) ic
= (ic
+1) % k
;
* 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
execl("/usr/lib/makekey", "-", 0);
execl("/lib/makekey", "-", 0);
write(pf
[1], buffer
, 10);
if (wait((int *)NULL
)==-1 || read(pf
[0], buffer
, 13)!=13)
error("crypt: cannot generate key");
/* end of nonportable part */