added ed, from Andrew Moore, alm@netcom.com
This commit is contained in:
parent
f6a28bf135
commit
9b082a69f0
|
@ -0,0 +1,9 @@
|
|||
# $Header: /cvsroot/src/bin/ed/Makefile,v 1.1 1993/04/08 01:07:16 cgd Exp $
|
||||
|
||||
PROG =ed
|
||||
CFLAGS+=-I${.CURDIR} -DDES -W -DGNU_REGEX
|
||||
SRCS= ed.c re.c buf.c cbc.c
|
||||
LDADD= -lgnuregex
|
||||
NOMAN= noman
|
||||
|
||||
.include <bsd.prog.mk>
|
|
@ -0,0 +1,17 @@
|
|||
ed is a POSIX-compliant line editor. It should work with any regular
|
||||
expression package that conforms to the POSIX interface standard, such as
|
||||
GNU regex(3).
|
||||
|
||||
The following compiler directives are recognized:
|
||||
GNU_REGEX - use with GNU regex(3)
|
||||
DES - use to add encryption support (requires crypt(3))
|
||||
NO_REALLOC_NULL - use if realloc(3) does not accept a NULL pointer
|
||||
|
||||
The file `ed-1003.2' in the ./doc directory describes POSIX ed. Extensions
|
||||
to the POSIX standard are described in the file `extensions.'
|
||||
|
||||
The ./test directory contains regression tests for ed. The README
|
||||
file in that directory explains how to run these.
|
||||
|
||||
For a description of the ed algorithm, see Kernighan and Pike's book
|
||||
"Software Tools in Pascal," Addison-Wesley, 1981.
|
|
@ -0,0 +1,217 @@
|
|||
/* buf.c: This file contains the scratch-file buffer rountines for the
|
||||
ed line editor. */
|
||||
/*-
|
||||
* Copyright (c) 1992 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Rodney Ruddock of the University of Guelph.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)buf.c 5.5 (Berkeley) 3/28/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/file.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "ed.h"
|
||||
|
||||
extern line_t line0;
|
||||
|
||||
FILE *sfp; /* scratch file pointer */
|
||||
off_t sfseek; /* scratch file position */
|
||||
int seek_write; /* seek before writing */
|
||||
|
||||
/* gettxt: get a line of text from the scratch file; return pointer
|
||||
to the text */
|
||||
char *
|
||||
gettxt(lp)
|
||||
line_t *lp;
|
||||
{
|
||||
static char txtbuf[MAXLINE];
|
||||
int len, ct;
|
||||
|
||||
if (lp == &line0)
|
||||
return NULL;
|
||||
seek_write = 1; /* force seek on write */
|
||||
/* out of position */
|
||||
if (sfseek != lp->seek) {
|
||||
sfseek = lp->seek;
|
||||
if (fseek(sfp, sfseek, SEEK_SET) < 0) {
|
||||
fprintf(stderr, "cannot seek temp file\n");
|
||||
return (char *) ERR;
|
||||
}
|
||||
}
|
||||
len = lp->len & ~ACTV;
|
||||
if ((ct = fread(txtbuf, sizeof(char), len, sfp)) < 0 || ct != len) {
|
||||
fprintf(stderr, "cannot read temp file\n");
|
||||
return (char *) ERR;
|
||||
}
|
||||
sfseek += len; /* update file position */
|
||||
txtbuf[len] = '\0';
|
||||
return txtbuf;
|
||||
}
|
||||
|
||||
|
||||
extern long curln;
|
||||
extern long lastln;
|
||||
|
||||
/* puttxt: write a line of text to the scratch file and add a line node
|
||||
to the editor buffer; return a pointer to the end of the text */
|
||||
char *
|
||||
puttxt(cs)
|
||||
char *cs;
|
||||
{
|
||||
line_t *lp;
|
||||
int len, ct;
|
||||
char *s;
|
||||
|
||||
if ((lp = (line_t *) malloc(sizeof(line_t))) == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return (char *) ERR;
|
||||
}
|
||||
/* assert: cs is '\n' terminated */
|
||||
for (s = cs; *s != '\n'; s++)
|
||||
;
|
||||
len = (s - cs) & ~ACTV;
|
||||
/* out of position */
|
||||
if (seek_write) {
|
||||
if (fseek(sfp, 0L, SEEK_END) < 0) {
|
||||
fprintf(stderr, "cannot seek temp file\n");
|
||||
return (char *) ERR;
|
||||
}
|
||||
sfseek = ftell(sfp);
|
||||
seek_write = 0;
|
||||
}
|
||||
/* assert: spl1() */
|
||||
if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
|
||||
sfseek = -1;
|
||||
fprintf(stderr, "cannot write temp file\n");
|
||||
return (char *) ERR;
|
||||
}
|
||||
lp->len = len;
|
||||
lp->seek = sfseek;
|
||||
lpqueue(lp);
|
||||
sfseek += len; /* update file position */
|
||||
return (*++s == '\0') ? NULL : s;
|
||||
}
|
||||
|
||||
|
||||
/* lpqueue: add a line node in the editor buffer after the current line */
|
||||
void
|
||||
lpqueue(lp)
|
||||
line_t *lp;
|
||||
{
|
||||
line_t *cp;
|
||||
|
||||
cp = getptr(curln); /* this getptr last! */
|
||||
insqueue(lp, cp);
|
||||
lastln++;
|
||||
curln++;
|
||||
}
|
||||
|
||||
|
||||
extern int mutex;
|
||||
extern int sigflags;
|
||||
|
||||
/* getptr: return pointer to a line node in the editor buffer */
|
||||
line_t *
|
||||
getptr(n)
|
||||
long n;
|
||||
{
|
||||
static line_t *lp = &line0;
|
||||
static long on = 0;
|
||||
|
||||
spl1();
|
||||
if (n > on)
|
||||
if (n <= (on + lastln) >> 1) {
|
||||
for (; on < n; on++)
|
||||
lp = lp->next;
|
||||
} else {
|
||||
lp = line0.prev;
|
||||
for (on = lastln; on > n; on--)
|
||||
lp = lp->prev;
|
||||
}
|
||||
else
|
||||
if (n >= on >> 1) {
|
||||
for (; on > n; on--)
|
||||
lp = lp->prev;
|
||||
} else {
|
||||
lp = &line0;
|
||||
for (on = 0; on < n; on++)
|
||||
lp = lp->next;
|
||||
}
|
||||
spl0();
|
||||
return lp;
|
||||
}
|
||||
|
||||
|
||||
char sfn[15] = ""; /* scratch file name */
|
||||
|
||||
/* sbopen: open scratch file */
|
||||
sbopen()
|
||||
{
|
||||
strcpy(sfn, "/tmp/ed.XXXXXX");
|
||||
if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) {
|
||||
fprintf(stderr, "cannot open temp file\n");
|
||||
return ERR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* sbclose: close scratch file */
|
||||
sbclose()
|
||||
{
|
||||
if (sfp) {
|
||||
unlink(sfn);
|
||||
fclose(sfp);
|
||||
sfp = NULL;
|
||||
}
|
||||
sfseek = seek_write = 0;
|
||||
}
|
||||
|
||||
|
||||
/* quit: remove scratch file and exit */
|
||||
void
|
||||
quit(n)
|
||||
int n;
|
||||
{
|
||||
if (sfp) {
|
||||
unlink(sfn);
|
||||
fclose(sfp);
|
||||
}
|
||||
exit(n);
|
||||
}
|
|
@ -0,0 +1,376 @@
|
|||
/* cbc.c: This file contains the encryption routines for the ed line editor */
|
||||
/*-
|
||||
* Copyright (c) 1991 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Matt Bishop of Dartmouth College.
|
||||
*
|
||||
* The United States Government has rights in this work pursuant
|
||||
* to contract no. NAG 2-680 between the National Aeronautics and
|
||||
* Space Administration and Dartmouth College.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)cbc.c 5.5 (Berkeley) 6/27/91";
|
||||
#endif /* not lint */
|
||||
|
||||
/* Author: Matt Bishop
|
||||
* Department of Mathematics and Computer Science
|
||||
* Dartmouth College
|
||||
* Hanover, NH 03755
|
||||
* Email: Matt.Bishop@dartmouth.edu
|
||||
* ...!decvax!dartvax!Matt.Bishop
|
||||
*
|
||||
* See Technical Report PCS-TR91-158, Department of Mathematics and Computer
|
||||
* Science, Dartmouth College, for a detailed description of the implemen-
|
||||
* tation and differences between it and Sun's. The DES is described in
|
||||
* FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
|
||||
* or the technical report for a complete reference).
|
||||
*/
|
||||
|
||||
#ifdef DES
|
||||
#include <errno.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
/*
|
||||
* Define a divisor for rand() that yields a uniform distribution in the
|
||||
* range 0-255.
|
||||
*/
|
||||
#define RAND_DIV (((unsigned) RAND_MAX + 1) >> 8)
|
||||
|
||||
/*
|
||||
* BSD and System V systems offer special library calls that do
|
||||
* block moves and fills, so if possible we take advantage of them
|
||||
*/
|
||||
#define MEMCPY(dest,src,len) bcopy((src),(dest),(len))
|
||||
#define MEMZERO(dest,len) bzero((dest),(len))
|
||||
|
||||
/* Hide the calls to the primitive encryption routines. */
|
||||
#define DES_KEY(buf) \
|
||||
if (des_setkey(buf)) \
|
||||
err("des_setkey");
|
||||
#define DES_XFORM(buf) \
|
||||
if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
|
||||
err("des_cipher");
|
||||
|
||||
/*
|
||||
* read/write - no error checking
|
||||
*/
|
||||
#define READ(buf, n, fp) fread(buf, sizeof(char), n, fp)
|
||||
#define WRITE(buf, n, fp) fwrite(buf, sizeof(char), n, fp)
|
||||
|
||||
/*
|
||||
* some things to make references easier
|
||||
*/
|
||||
typedef char Desbuf[8];
|
||||
#define CHAR(x,i) (x[i])
|
||||
#define UCHAR(x,i) (x[i])
|
||||
#define BUFFER(x) (x)
|
||||
#define UBUFFER(x) (x)
|
||||
|
||||
/*
|
||||
* global variables and related macros
|
||||
*/
|
||||
|
||||
enum { /* encrypt, decrypt, authenticate */
|
||||
MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
|
||||
} mode = MODE_ENCRYPT;
|
||||
|
||||
Desbuf ivec; /* initialization vector */
|
||||
Desbuf pvec; /* padding vector */
|
||||
char bits[] = { /* used to extract bits from a char */
|
||||
'\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
|
||||
};
|
||||
int pflag; /* 1 to preserve parity bits */
|
||||
|
||||
/*
|
||||
* initialize cbc
|
||||
*/
|
||||
void
|
||||
cbcinit()
|
||||
{
|
||||
int i;
|
||||
|
||||
/* initialize the initialization vctor */
|
||||
MEMZERO(ivec, 8);
|
||||
|
||||
/* intialize the padding vector */
|
||||
srand((unsigned) time((time_t *) 0));
|
||||
for (i = 0; i < 8; i++)
|
||||
CHAR(pvec, i) = (char) (rand()/RAND_DIV);
|
||||
}
|
||||
|
||||
/*
|
||||
* get keyword from tty or stdin
|
||||
*/
|
||||
getkey()
|
||||
{
|
||||
register char *p; /* used to obtain the key */
|
||||
Desbuf msgbuf; /* I/O buffer */
|
||||
|
||||
/*
|
||||
* get the key
|
||||
*/
|
||||
if (*(p = getpass("Enter key: "))) {
|
||||
|
||||
/*
|
||||
* copy it, nul-padded, into the key area
|
||||
*/
|
||||
cvtkey(BUFFER(msgbuf), p);
|
||||
MEMZERO(p, _PASSWORD_LEN);
|
||||
makekey(msgbuf);
|
||||
MEMZERO(msgbuf, sizeof msgbuf);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* print a warning message and, possibly, terminate
|
||||
*/
|
||||
err(s)
|
||||
char *s; /* the message */
|
||||
{
|
||||
(void)fprintf(stderr, "?%s\n", s ? s : strerror(errno));
|
||||
}
|
||||
|
||||
/*
|
||||
* map a hex character to an integer
|
||||
*/
|
||||
tobinhex(c, radix)
|
||||
char c; /* char to be converted */
|
||||
int radix; /* base (2 to 16) */
|
||||
{
|
||||
switch(c) {
|
||||
case '0': return(0x0);
|
||||
case '1': return(0x1);
|
||||
case '2': return(radix > 2 ? 0x2 : -1);
|
||||
case '3': return(radix > 3 ? 0x3 : -1);
|
||||
case '4': return(radix > 4 ? 0x4 : -1);
|
||||
case '5': return(radix > 5 ? 0x5 : -1);
|
||||
case '6': return(radix > 6 ? 0x6 : -1);
|
||||
case '7': return(radix > 7 ? 0x7 : -1);
|
||||
case '8': return(radix > 8 ? 0x8 : -1);
|
||||
case '9': return(radix > 9 ? 0x9 : -1);
|
||||
case 'A': case 'a': return(radix > 10 ? 0xa : -1);
|
||||
case 'B': case 'b': return(radix > 11 ? 0xb : -1);
|
||||
case 'C': case 'c': return(radix > 12 ? 0xc : -1);
|
||||
case 'D': case 'd': return(radix > 13 ? 0xd : -1);
|
||||
case 'E': case 'e': return(radix > 14 ? 0xe : -1);
|
||||
case 'F': case 'f': return(radix > 15 ? 0xf : -1);
|
||||
}
|
||||
/*
|
||||
* invalid character
|
||||
*/
|
||||
return(-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* convert the key to a bit pattern
|
||||
*/
|
||||
cvtkey(obuf, ibuf)
|
||||
char *obuf; /* bit pattern */
|
||||
char *ibuf; /* the key itself */
|
||||
{
|
||||
register int i, j; /* counter in a for loop */
|
||||
int nbuf[64]; /* used for hex/key translation */
|
||||
|
||||
/*
|
||||
* leading '0x' or '0X' == hex key
|
||||
*/
|
||||
if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
|
||||
ibuf = &ibuf[2];
|
||||
/*
|
||||
* now translate it, bombing on any illegal hex digit
|
||||
*/
|
||||
for (i = 0; ibuf[i] && i < 16; i++)
|
||||
if ((nbuf[i] = tobinhex(ibuf[i], 16)) == -1)
|
||||
err("bad hex digit in key");
|
||||
while (i < 16)
|
||||
nbuf[i++] = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
obuf[i] =
|
||||
((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
|
||||
/* preserve parity bits */
|
||||
pflag = 1;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* leading '0b' or '0B' == binary key
|
||||
*/
|
||||
if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
|
||||
ibuf = &ibuf[2];
|
||||
/*
|
||||
* now translate it, bombing on any illegal binary digit
|
||||
*/
|
||||
for (i = 0; ibuf[i] && i < 16; i++)
|
||||
if ((nbuf[i] = tobinhex(ibuf[i], 2)) == -1)
|
||||
err("bad binary digit in key");
|
||||
while (i < 64)
|
||||
nbuf[i++] = 0;
|
||||
for (i = 0; i < 8; i++)
|
||||
for (j = 0; j < 8; j++)
|
||||
obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
|
||||
/* preserve parity bits */
|
||||
pflag = 1;
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* no special leader -- ASCII
|
||||
*/
|
||||
(void)strncpy(obuf, ibuf, 8);
|
||||
}
|
||||
|
||||
/*****************
|
||||
* DES FUNCTIONS *
|
||||
*****************/
|
||||
/*
|
||||
* This sets the DES key and (if you're using the deszip version)
|
||||
* the direction of the transformation. This uses the Sun
|
||||
* to map the 64-bit key onto the 56 bits that the key schedule
|
||||
* generation routines use: the old way, which just uses the user-
|
||||
* supplied 64 bits as is, and the new way, which resets the parity
|
||||
* bit to be the same as the low-order bit in each character. The
|
||||
* new way generates a greater variety of key schedules, since many
|
||||
* systems set the parity (high) bit of each character to 0, and the
|
||||
* DES ignores the low order bit of each character.
|
||||
*/
|
||||
makekey(buf)
|
||||
Desbuf buf; /* key block */
|
||||
{
|
||||
register int i, j; /* counter in a for loop */
|
||||
register int par; /* parity counter */
|
||||
|
||||
/*
|
||||
* if the parity is not preserved, flip it
|
||||
*/
|
||||
if (!pflag) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
par = 0;
|
||||
for (j = 1; j < 8; j++)
|
||||
if ((bits[j]&UCHAR(buf, i)) != 0)
|
||||
par++;
|
||||
if ((par&01) == 01)
|
||||
UCHAR(buf, i) = UCHAR(buf, i)&0177;
|
||||
else
|
||||
UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
|
||||
}
|
||||
}
|
||||
|
||||
DES_KEY(UBUFFER(buf));
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This encrypts using the Cipher Block Chaining mode of DES
|
||||
*/
|
||||
cbcenc(msgbuf, n, fp)
|
||||
char *msgbuf;
|
||||
int n;
|
||||
FILE *fp;
|
||||
{
|
||||
int inverse = 0; /* 0 to encrypt, 1 to decrypt */
|
||||
|
||||
/*
|
||||
* do the transformation
|
||||
*/
|
||||
if (n == 8) {
|
||||
for (n = 0; n < 8; n++)
|
||||
CHAR(msgbuf, n) ^= CHAR(ivec, n);
|
||||
DES_XFORM(UBUFFER(msgbuf));
|
||||
MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
|
||||
return WRITE(BUFFER(msgbuf), 8, fp);
|
||||
}
|
||||
/*
|
||||
* at EOF or last block -- in either case, the last byte contains
|
||||
* the character representation of the number of bytes in it
|
||||
*/
|
||||
/*
|
||||
MEMZERO(msgbuf + n, 8 - n);
|
||||
*/
|
||||
/*
|
||||
* Pad the last block randomly
|
||||
*/
|
||||
(void)MEMCPY(BUFFER(msgbuf + n), BUFFER(pvec), 8 - n);
|
||||
CHAR(msgbuf, 7) = n;
|
||||
for (n = 0; n < 8; n++)
|
||||
CHAR(msgbuf, n) ^= CHAR(ivec, n);
|
||||
DES_XFORM(UBUFFER(msgbuf));
|
||||
return WRITE(BUFFER(msgbuf), 8, fp);
|
||||
}
|
||||
|
||||
/*
|
||||
* This decrypts using the Cipher Block Chaining mode of DES
|
||||
*/
|
||||
cbcdec(msgbuf, fp)
|
||||
char *msgbuf; /* I/O buffer */
|
||||
FILE *fp; /* input file descriptor */
|
||||
{
|
||||
Desbuf ibuf; /* temp buffer for initialization vector */
|
||||
register int n; /* number of bytes actually read */
|
||||
register int c; /* used to test for EOF */
|
||||
register int bn; /* block number */
|
||||
int inverse = 1; /* 0 to encrypt, 1 to decrypt */
|
||||
|
||||
if ((n = READ(BUFFER(msgbuf), 8, fp)) == 8) {
|
||||
/*
|
||||
* do the transformation
|
||||
*/
|
||||
MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
|
||||
DES_XFORM(UBUFFER(msgbuf));
|
||||
for (c = 0; c < 8; c++)
|
||||
UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
|
||||
MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
|
||||
/*
|
||||
* if the last one, handle it specially
|
||||
*/
|
||||
if ((c = fgetc(fp)) == EOF) {
|
||||
n = CHAR(msgbuf, 7);
|
||||
if (n < 0 || n > 7) {
|
||||
err("decryption failed (block corrupted)");
|
||||
return EOF;
|
||||
}
|
||||
} else
|
||||
(void)ungetc(c, fp);
|
||||
return n;
|
||||
}
|
||||
if (n > 0)
|
||||
err("decryption failed (incomplete block)");
|
||||
return EOF;
|
||||
}
|
||||
#endif /* DES */
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,50 @@
|
|||
This version of ed is not strictly POSIX compliant, as described in the
|
||||
POSIX 1003.2 Draft 11.2 document (see the file `ed-1003.2'). BSD commands
|
||||
have been implemented wherever they do not conflict with the POSIX
|
||||
standard. This includes the BSD `W' command for appending text to an
|
||||
existing file; the BSD `s' command (i.e., s[rgp]*) to repeat a previous
|
||||
substitution; the BSD `z' command for scrolling through the buffer; and
|
||||
the BSD `wq' command for exiting after write. BSD line addressing syntax
|
||||
(i.e., `^' and `%' - see the file `legal.addrs') is also recognized.
|
||||
|
||||
The POSIX interactive global commands `G' and `V' are extended to support
|
||||
multiple commands, including `a', `i' and `c'. The command format is the
|
||||
same as for the global commands `g' and `v', i.e., one command per line
|
||||
with each line, except for the last, ending in a backslash (\).
|
||||
|
||||
If crypt is available, files can be read and written using DES encryption.
|
||||
The `x' command prompts the user to enter a key for encrypting/decrypting
|
||||
subsequent reads and writes. If only a newline is entered as the key,
|
||||
then encryption is disabled. Otherwise, a key is read with echoing turned
|
||||
off until a newline is entered. For more information on the encryption
|
||||
algorithm, see the bdes(1) man page. Encryption/decryption should be
|
||||
fully compatible with SunOS DES.
|
||||
|
||||
An extension to the POSIX file commands `E', `e', `r', `W' and `w' is that
|
||||
<file> arguments are processed for backslash (\) escapes, i.e., any
|
||||
character preceded by a backslash is interpreted literally. A trailing
|
||||
backslash is ignored. If the first unescaped character of a <file>
|
||||
argument is a bang (!), then the rest of the line is interpreted as a
|
||||
shell command and no escape processing is performed by ed. This rule does
|
||||
not apply to the 'f' command (described below).
|
||||
|
||||
While the default file name cannot be set to a shell command (i.e.,
|
||||
!<shell-cmd>) via any of the `r', `w', and `e' commands, POSIX evidently
|
||||
does not preclude using the `f' command for this purpose. Upon reading
|
||||
or writing the default file when its name begins with a bang (!), ed
|
||||
interprets the rest of the line as a shell command and attempts to execute
|
||||
it. Escape processing is not performed in this case. The `f' command
|
||||
can be used in this way as a simple macro function. For example, after
|
||||
setting the default file name to `!echo hello, world', the command `.r'
|
||||
inserts the line `hello world' after the current line. The `f' command
|
||||
with no arguments prints the default unescaped file name.
|
||||
|
||||
--
|
||||
The following commands are neither part of POSIX 1003.2 D11/2 nor are
|
||||
they supported in this version of ed.
|
||||
|
||||
The vi command: (addr1,addr2) !<shell-cmd> which replaces a range of
|
||||
lines with the output of a shell command is not supported.
|
||||
|
||||
The vi command: [rwe] !!, where !! is replaced by the previous
|
||||
!<shell-cmd> is not supported.
|
|
@ -0,0 +1,50 @@
|
|||
The following describes line addressing syntax. This is a combination of
|
||||
both BSD and POSIX.
|
||||
|
||||
Addresses are computed from left to right relative to the current address.
|
||||
|
||||
Addresses in a pair are separated by either a comma or a semi-colon. If
|
||||
a semi-colon is used as a separator instead of a comma, then the pair is
|
||||
interpreted as only a single address (though syntactically still a pair)
|
||||
as follows: the first address is computed, and the current address is
|
||||
set to this address; then the second address is computed relative to the
|
||||
new current address.
|
||||
|
||||
If multiple separated addresses are given, then only the last pair is
|
||||
used. Address pairs are not legal where only a single address is expected.
|
||||
|
||||
Addresses may be composed of the following:
|
||||
. - current line
|
||||
$ - last line
|
||||
- - previous line - may be repeated
|
||||
-<n> - <n>th previous line, where <n> is a non-negative number
|
||||
^ - previous line - may be repeated (BSD)
|
||||
^<n> - <n>th previous line, where <n> is a non-negative number
|
||||
+ - next line - may be repeated
|
||||
+<n> - <n>th next line, where <n> is a non-negative number
|
||||
% - first through last lines (BSD), i.e., equivalent to: 1,$
|
||||
, - first through last lines (POSIX), i.e., equivalent to: 1,$
|
||||
; - current through last lines (POSIX), i.e., equivalent to: .,$
|
||||
/pat/ - next line containing pattern pat
|
||||
?pat? - previous line containing pattern pat
|
||||
[0-9]* - line <n>, where <n> is a decimal number in the range [0,$]
|
||||
<ws><n> - any whitespace <ws> after the first address followed by a number
|
||||
nn is interpreted as +nn
|
||||
'<lc> - line previously marked by k command, where <lc> is a
|
||||
lower case letter
|
||||
|
||||
After the first component of an address, only digits, whitespace and
|
||||
increments (i.e., `+', `-', and '^') are legal. Leading whitespace is
|
||||
ignored.
|
||||
|
||||
Examples:
|
||||
The address pair 0;+1 is equivalent to the single address 1.
|
||||
The address triple 4;-1,$ is equivalent to the address pair 3,$.
|
||||
The address triple 1,$;-1 is equivalent only to the single address $-1.
|
||||
If the current line is 1, then the address triple +1,+2,+3 is equivalent
|
||||
to the pair 3,4.
|
||||
If the current line is 1, then the address triple +1;+2,+3 is equivalent
|
||||
to the pair 4,5.
|
||||
The command t$;-1 is invalid because, syntactically, $;-1 is an address
|
||||
pair. The correct syntax is t$-.
|
||||
The command 0;/pat/;// prints the second line containing the pattern pat.
|
|
@ -0,0 +1,48 @@
|
|||
The following commands are recognized. These are a combination of BSD
|
||||
and POSIX. The POSIX version of a command always overrides any
|
||||
BSD version. The commands are shown together with their permissible number
|
||||
of addresses.
|
||||
|
||||
!<shell-cmd> - run <shell-cmd> via sh {1} (POSIX)
|
||||
($)= - print line number
|
||||
E <file> - edit a file unconditionally {1}
|
||||
E !<shell-cmd> - edit the standard output of <shell-cmd> {1} (POSIX)
|
||||
(1,$)G/pat/ - interactively edit lines matching a pattern (POSIX) {1}
|
||||
H - print explanations of all errors (POSIX)
|
||||
P - toggle command prompt (POSIX)
|
||||
Q - quit ed unconditionally
|
||||
(1,$)V - interactively edit lines not matching a pattern (POSIX) {1}
|
||||
(1,$)W - append lines to a file (BSD)
|
||||
(.)a - append text to the buffer
|
||||
(.,.)c - change lines in the buffer
|
||||
(.,.)d - delete lines from the buffer
|
||||
e <file> - edit a file {1}
|
||||
e !<shell-cmd> - edit the standard output of shell-cmd {1} (POSIX)
|
||||
f <file> - set the default file to <file> {1}
|
||||
(1,$)g/pat/<cmd-list> - apply <cmd-list> to lines matching a pattern
|
||||
h - print explanation of the last error (POSIX)
|
||||
(.)i - insert text in the buffer
|
||||
(.,.+1)j - join lines in the buffer
|
||||
(.)k<lc> - mark a line for later '<lc> addressing
|
||||
(.,.)l - print lines unambiguously to stdout
|
||||
(.,.)m<addr> - move lines in the buffer
|
||||
(.,.)n - enumerate lines to stdout (POSIX)
|
||||
(.,.)p - print lines to stdout
|
||||
q - quit ed
|
||||
($)r <file> - read a file {1}
|
||||
($)r !<shell-cmd> - read the stdout of <shell-cmd> {1} (POSIX)
|
||||
(.,.)s/pat/sub/g - substitute matching text in a line via a template
|
||||
(.,.)s/pat/sub/<n> - substitute the <n>th match in a line (POSIX)
|
||||
(.,.)s[rgp]* - repeat the last substitution (BSD)
|
||||
(.,.)t<addr> - copy (transfer) lines in the buffer
|
||||
u - undo the last command (POSIX)
|
||||
(1,$)v/pat/<cmd-list> - apply <cmd-list> to lines not matching a pattern
|
||||
(1,$)w <file> - write lines in the buffer to a file
|
||||
(1,$)w !<shell-cmd> - write lines to the stdin of <shell-cmd> (POSIX)
|
||||
x - prompt for an encryption key (SunOS) {1}
|
||||
(.,.+22)z - page lines in the buffer to stdout (BSD)
|
||||
(.,.)<newline> - print lines to stdout (BSD)
|
||||
|
||||
--
|
||||
{1} See the file `extensions' for additional information on these
|
||||
commands.
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,204 @@
|
|||
/* ed.h: type and constant definitions for the ed editor. */
|
||||
/*
|
||||
* Copyright (c) 1993 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* Andrew Moore, Talke Studio.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ed.h 5.5 (Berkeley) 3/28/93
|
||||
*/
|
||||
|
||||
#include <unistd.h>
|
||||
# include <regex.h>
|
||||
#if defined(BSD) && BSD >= 199103 || defined(__386BSD__)
|
||||
# include <sys/param.h> /* for MAXPATHLEN */
|
||||
#endif
|
||||
|
||||
#define BITSPERBYTE 8
|
||||
#define BITS(type) (BITSPERBYTE * (int)sizeof(type))
|
||||
#define CHARBITS BITS(char)
|
||||
#define INTBITS BITS(int)
|
||||
|
||||
#define ESCHAR '\\'
|
||||
#define CCL '[' /* Character class: [...] */
|
||||
#define CCLEND ']'
|
||||
#define DITTO '&'
|
||||
|
||||
/* sigflags values */
|
||||
#define SIG_INT 1
|
||||
#define SIG_HUP 2
|
||||
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define ERR (-2)
|
||||
#define EMOD (ERR - 1)
|
||||
|
||||
#ifndef MAXPATHLEN
|
||||
# define MAXPATHLEN 255 /* _POSIX_PATH_MAX */
|
||||
#endif
|
||||
|
||||
#define MAXFNAME MAXPATHLEN /* max file name size */
|
||||
#define MAXLINE (4 << 10) /* max number of chars per line */
|
||||
#define SE_MAX 30 /* max subexpressions in a regular expression */
|
||||
|
||||
typedef regex_t pattern_t;
|
||||
|
||||
#ifdef GNU_REGEX
|
||||
# define FASTMAP_SIZE 256 /* size of fastmap for 8 bit character set */
|
||||
#endif
|
||||
|
||||
/* Line node */
|
||||
typedef struct line {
|
||||
struct line *next;
|
||||
struct line *prev;
|
||||
off_t seek; /* address of line in scratch buffer */
|
||||
|
||||
#define ACTV (1 << (INTBITS - 1)) /* active status: high bit of len */
|
||||
|
||||
int len; /* length of line */
|
||||
} line_t;
|
||||
|
||||
|
||||
typedef struct undo {
|
||||
|
||||
/* type of undo nodes */
|
||||
#define UADD 0
|
||||
#define UDEL 1
|
||||
|
||||
int type; /* command type */
|
||||
line_t *h; /* head of list */
|
||||
line_t *t; /* tail of list */
|
||||
} undo_t;
|
||||
|
||||
#ifndef max
|
||||
# define max(a,b) ((a) > (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
#ifndef min
|
||||
# define min(a,b) ((a) < (b) ? (a) : (b))
|
||||
#endif
|
||||
|
||||
/* nextln: return line after l wrt k */
|
||||
#define nextln(l,k) ((l)+1 > (k) ? 0 : (l)+1)
|
||||
|
||||
/* nextln: return line before l wrt k */
|
||||
#define prevln(l,k) ((l)-1 < 0 ? (k) : (l)-1)
|
||||
|
||||
#define skipblanks() while (isspace(*ibufp) && *ibufp != '\n') ibufp++
|
||||
|
||||
/* spl1: disable some interrupts (requires reliable signals) */
|
||||
#define spl1() mutex++
|
||||
|
||||
/* spl0: enable all interrupts; check sigflags (requires reliable signals) */
|
||||
#define spl0() \
|
||||
if (--mutex == 0) { \
|
||||
if (sigflags & SIG_HUP) dohup(); \
|
||||
if (sigflags & SIG_INT) dointr(); \
|
||||
}
|
||||
|
||||
/* requeue: link pred before succ */
|
||||
#define requeue(pred, succ) (pred)->next = (succ), (succ)->prev = (pred)
|
||||
|
||||
/* insqueue: insert elem in circular queue after pred */
|
||||
#define insqueue(elem, pred) \
|
||||
{ \
|
||||
requeue((elem), (pred)->next); \
|
||||
requeue((pred), elem); \
|
||||
}
|
||||
|
||||
/* remqueue: remove elem from circular queue */
|
||||
#define remqueue(elem) requeue((elem)->prev, (elem)->next);
|
||||
|
||||
#ifndef __P
|
||||
# ifndef __STDC__
|
||||
# define __P(proto) ()
|
||||
# else
|
||||
# define __P(proto) proto
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/* local function declarations */
|
||||
int append __P((long, int));
|
||||
int cbcdec __P((char *, FILE *));
|
||||
int cbcenc __P((char *, int, FILE *));
|
||||
void cbcinit __P((void));
|
||||
int ckglob __P((void));
|
||||
int deflt __P((long, long));
|
||||
int del __P((long, long));
|
||||
int desgetc __P((FILE *));
|
||||
FILE *desopen __P((char *, char *));
|
||||
int desputc __P((int, FILE *));
|
||||
int docmd __P((int));
|
||||
char *ccl __P((int, char *));
|
||||
long doglob __P((void));
|
||||
void dohup __P((void));
|
||||
void dointr __P((void));
|
||||
int doprnt __P((long, long, int));
|
||||
long doread __P((long, char *));
|
||||
long dowrite __P((long, long, char *, char *));
|
||||
char *esctos __P((char *));
|
||||
long find __P((pattern_t *, int));
|
||||
void freecmdv __P((void));
|
||||
char *getcmdv __P((void));
|
||||
char *getfn __P((void));
|
||||
int getkey __P((void));
|
||||
char *getlhs __P((int));
|
||||
int getline __P((char *, int));
|
||||
int getlist __P((void));
|
||||
long getnum __P((int));
|
||||
long getone __P((void));
|
||||
line_t *getptr __P((long));
|
||||
long getrange __P((line_t *, line_t *));
|
||||
int getrhs __P((char *, int));
|
||||
char *gettxt __P((line_t *));
|
||||
undo_t *getuptr __P((int, long, long));
|
||||
int join __P((long, long));
|
||||
line_t *lpdup __P((line_t *));
|
||||
void lpqueue __P((line_t *));
|
||||
char *makesub __P((char *, int, int));
|
||||
int move __P((long, int));
|
||||
int oddesc __P((char *, char *));
|
||||
void onhup __P((int));
|
||||
void onintr __P((int));
|
||||
pattern_t *optpat __P((void));
|
||||
void prntln __P((char *, long, int));
|
||||
char *puttxt __P((char *));
|
||||
void quit __P((int));
|
||||
char *regsub __P((pattern_t *, char *, char *, int));
|
||||
int sbclose __P((void));
|
||||
int sbopen __P((void));
|
||||
int sgetline __P((char *, int, FILE *));
|
||||
char *subcat __P((char *, regmatch_t *, char *, char *, char *));
|
||||
int subst __P((pattern_t *, char *, int));
|
||||
int transfer __P((long));
|
||||
int undo __P((void));
|
||||
void ureset __P((void));
|
|
@ -0,0 +1,142 @@
|
|||
/* re.c: This file contains the regular expression interface routines for
|
||||
the ed line editor. */
|
||||
/*-
|
||||
* Copyright (c) 1993 The Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley
|
||||
* by Andrew Moore, Talke Studio.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char sccsid[] = "@(#)re.c 5.5 (Berkeley) 3/28/93";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ed.h"
|
||||
|
||||
extern char *ibufp;
|
||||
extern int patlock;
|
||||
|
||||
char errmsg[MAXFNAME + 40] = "";
|
||||
|
||||
/* optpat: return pointer to compiled pattern from command buffer */
|
||||
pattern_t *
|
||||
optpat()
|
||||
{
|
||||
static pattern_t *exp = NULL;
|
||||
|
||||
char *exps;
|
||||
char delim;
|
||||
int n;
|
||||
|
||||
if ((delim = *ibufp) == '\n')
|
||||
return exp;
|
||||
else if (delim == ' ' || *++ibufp == '\n') {
|
||||
sprintf(errmsg, "invalid pattern delimiter");
|
||||
return NULL;
|
||||
} else if (*ibufp == delim)
|
||||
return exp;
|
||||
else if ((exps = getlhs(delim)) == NULL)
|
||||
return NULL;
|
||||
/* buffer alloc'd && not reserved */
|
||||
if (exp && !patlock)
|
||||
regfree(exp);
|
||||
else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
return NULL;
|
||||
}
|
||||
patlock = 0;
|
||||
#ifdef GNU_REGEX
|
||||
/* initialize pattern buffer */
|
||||
exp->buffer = NULL;
|
||||
exp->allocated = 0L;
|
||||
exp->fastmap = (char *) malloc(FASTMAP_SIZE);
|
||||
exp->translate = 0;
|
||||
#endif
|
||||
if (n = regcomp(exp, exps, 0)) {
|
||||
regerror(n, exp, errmsg, sizeof errmsg);
|
||||
return NULL;
|
||||
}
|
||||
return exp;
|
||||
}
|
||||
|
||||
|
||||
/* getlhs: copy a pattern string from the command buffer; return pointer
|
||||
to the copy */
|
||||
char *
|
||||
getlhs(delim)
|
||||
int delim;
|
||||
{
|
||||
static char buf[MAXLINE];
|
||||
char *nd;
|
||||
|
||||
for (nd = ibufp; *nd != delim && *nd != '\n'; nd++)
|
||||
switch (*nd) {
|
||||
default:
|
||||
break;
|
||||
case CCL:
|
||||
if ((nd = ccl(CCLEND, ++nd)) == NULL) {
|
||||
sprintf(errmsg, "unbalanced brackets ([])");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
case ESCHAR:
|
||||
if (*++nd == '\n') {
|
||||
sprintf(errmsg, "trailing backslash (\\)");
|
||||
return NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
strncpy(buf, ibufp, nd - ibufp);
|
||||
buf[nd - ibufp] = '\0';
|
||||
ibufp = nd;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/* ccl: expand a character class */
|
||||
char *
|
||||
ccl(delim, src)
|
||||
int delim;
|
||||
char *src;
|
||||
{
|
||||
if (*src == '^')
|
||||
src++;
|
||||
if (*src == delim)
|
||||
src++;
|
||||
while (*src != delim && *src != '\n')
|
||||
src++;
|
||||
return (*src == delim) ? src : NULL;
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \!.d
|
||||
!read one
|
||||
hello, world
|
||||
a
|
||||
okay
|
||||
.
|
||||
w \!.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
okay
|
|
@ -0,0 +1 @@
|
|||
okay
|
|
@ -0,0 +1,5 @@
|
|||
!read one
|
||||
hello, world
|
||||
a
|
||||
okay
|
||||
.
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,16 @@
|
|||
ED= ../ed
|
||||
|
||||
all: mkscripts ckscripts
|
||||
|
||||
mkscripts: mkscripts.sh
|
||||
@echo building test scripts...
|
||||
@chmod +x mkscripts.sh
|
||||
@ED=${ED} mkscripts.sh
|
||||
|
||||
ckscripts: ckscripts.sh
|
||||
@echo running test scripts...
|
||||
@chmod +x ckscripts.sh
|
||||
@ED=${ED} ckscripts.sh
|
||||
|
||||
clean:
|
||||
rm -f *.ed *.[oz]
|
|
@ -0,0 +1,18 @@
|
|||
The .t and .d and .r files in this directory are used for testing ed.
|
||||
To run the tests, set the ED variable in the Makefile for the path name
|
||||
of the program to be tested (e.g., /bin/ed), and type `make'.
|
||||
|
||||
Some spurious data may appear as the test runs. Errors appear
|
||||
as:
|
||||
*** The script u.ed exited abnormally ***
|
||||
or:
|
||||
*** Output u.o of script u.ed is incorrect ***
|
||||
|
||||
It is assumed that the ed being tested processes escapes (\) in file names.
|
||||
This is so that a name starting with bang (!) can be read, via:
|
||||
r \!file
|
||||
Without the escape, a POSIX ed would attempt to read the output of
|
||||
the shell command `file'.
|
||||
|
||||
Though numerous, the tests are very incomplete. Please send any new
|
||||
tests/bug reports to: alm@netcom.com
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \a.d
|
||||
0a
|
||||
hello world
|
||||
.
|
||||
2a
|
||||
hello world!
|
||||
.
|
||||
$a
|
||||
hello world!!
|
||||
.
|
||||
w \a.o
|
||||
EOT
|
|
@ -0,0 +1,8 @@
|
|||
hello world
|
||||
line 1
|
||||
hello world!
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
hello world!!
|
|
@ -0,0 +1,8 @@
|
|||
hello world
|
||||
line 1
|
||||
hello world!
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
hello world!!
|
|
@ -0,0 +1,9 @@
|
|||
0a
|
||||
hello world
|
||||
.
|
||||
2a
|
||||
hello world!
|
||||
.
|
||||
$a
|
||||
hello world!!
|
||||
.
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,17 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \c.d
|
||||
1c
|
||||
at the top
|
||||
.
|
||||
4c
|
||||
in the middle
|
||||
.
|
||||
$c
|
||||
at the bottom
|
||||
.
|
||||
2,3c
|
||||
between top/middle
|
||||
.
|
||||
w \c.o
|
||||
EOT
|
|
@ -0,0 +1,4 @@
|
|||
at the top
|
||||
between top/middle
|
||||
in the middle
|
||||
at the bottom
|
|
@ -0,0 +1,4 @@
|
|||
at the top
|
||||
between top/middle
|
||||
in the middle
|
||||
at the bottom
|
|
@ -0,0 +1,12 @@
|
|||
1c
|
||||
at the top
|
||||
.
|
||||
4c
|
||||
in the middle
|
||||
.
|
||||
$c
|
||||
at the bottom
|
||||
.
|
||||
2,3c
|
||||
between top/middle
|
||||
.
|
|
@ -0,0 +1,22 @@
|
|||
#!/bin/sh -
|
||||
# This script runs the .ed scripts generated by mkscripts.sh
|
||||
# and compares their output against the .r files, which contain
|
||||
# the correct output
|
||||
|
||||
PATH="/bin:/usr/bin:/usr/local/bin/:."
|
||||
[ X"$ED" = X ] && ED="../ed"
|
||||
|
||||
for i in *.ed; do
|
||||
base=`echo $i | sed 's/\..*/'`
|
||||
# base=`$ED - <<-EOF
|
||||
# r !echo $i
|
||||
# s/\..*
|
||||
# EOF`
|
||||
if $base.ed >/dev/null 2>&1; then
|
||||
if cmp -s $base.o $base.r; then :; else
|
||||
echo "*** Output $base.o of script $i is incorrect ***"
|
||||
fi
|
||||
else
|
||||
echo "*** The script $i exited abnormally ***"
|
||||
fi
|
||||
done
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \d.d
|
||||
1d
|
||||
2,3d
|
||||
$d
|
||||
w \d.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
line 2
|
|
@ -0,0 +1 @@
|
|||
line 2
|
|
@ -0,0 +1,3 @@
|
|||
1d
|
||||
2,3d
|
||||
$d
|
|
@ -0,0 +1 @@
|
|||
hello world
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \e1.d
|
||||
E e1.t
|
||||
w \e1.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
E e1.t
|
|
@ -0,0 +1 @@
|
|||
E e1.t
|
|
@ -0,0 +1 @@
|
|||
E e1.t
|
|
@ -0,0 +1 @@
|
|||
E !echo hello world-
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \e2.d
|
||||
E !echo hello world-
|
||||
w \e2.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
hello world-
|
|
@ -0,0 +1 @@
|
|||
hello world-
|
|
@ -0,0 +1 @@
|
|||
E !echo hello world-
|
|
@ -0,0 +1 @@
|
|||
E !echo hello world-
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \e3.d
|
||||
E
|
||||
w \e3.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
E !echo hello world-
|
|
@ -0,0 +1 @@
|
|||
E !echo hello world-
|
|
@ -0,0 +1 @@
|
|||
E
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,11 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \g1.d
|
||||
g/./m0
|
||||
g/./s/$/\
|
||||
hello world
|
||||
g/hello /s/lo/p!/\
|
||||
a\
|
||||
order
|
||||
w \g1.o
|
||||
EOT
|
|
@ -0,0 +1,15 @@
|
|||
line5
|
||||
help! world
|
||||
order
|
||||
line 4
|
||||
help! world
|
||||
order
|
||||
line 3
|
||||
help! world
|
||||
order
|
||||
line 2
|
||||
help! world
|
||||
order
|
||||
line 1
|
||||
help! world
|
||||
order
|
|
@ -0,0 +1,15 @@
|
|||
line5
|
||||
help! world
|
||||
order
|
||||
line 4
|
||||
help! world
|
||||
order
|
||||
line 3
|
||||
help! world
|
||||
order
|
||||
line 2
|
||||
help! world
|
||||
order
|
||||
line 1
|
||||
help! world
|
||||
order
|
|
@ -0,0 +1,6 @@
|
|||
g/./m0
|
||||
g/./s/$/\
|
||||
hello world
|
||||
g/hello /s/lo/p!/\
|
||||
a\
|
||||
order
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \g2.d
|
||||
g/[2-4]/-1,+1c\
|
||||
hello world
|
||||
w \g2.o
|
||||
EOT
|
|
@ -0,0 +1 @@
|
|||
hello world
|
|
@ -0,0 +1 @@
|
|||
hello world
|
|
@ -0,0 +1,2 @@
|
|||
g/[2-4]/-1,+1c\
|
||||
hello world
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,14 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \i.d
|
||||
1i
|
||||
hello world
|
||||
.
|
||||
2i
|
||||
hello world!
|
||||
.
|
||||
$i
|
||||
hello world!!
|
||||
.
|
||||
w \i.o
|
||||
EOT
|
|
@ -0,0 +1,8 @@
|
|||
hello world
|
||||
hello world!
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
hello world!!
|
||||
line5
|
|
@ -0,0 +1,8 @@
|
|||
hello world
|
||||
hello world!
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
hello world!!
|
||||
line5
|
|
@ -0,0 +1,9 @@
|
|||
1i
|
||||
hello world
|
||||
.
|
||||
2i
|
||||
hello world!
|
||||
.
|
||||
$i
|
||||
hello world!!
|
||||
.
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \j.d
|
||||
1,1j
|
||||
2,3j
|
||||
w \j.o
|
||||
EOT
|
|
@ -0,0 +1,4 @@
|
|||
line 1
|
||||
line 2line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,4 @@
|
|||
line 1
|
||||
line 2line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,2 @@
|
|||
1,1j
|
||||
2,3j
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \l.d
|
||||
w \l.o
|
||||
EOT
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,12 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \m.d
|
||||
1,2m$
|
||||
1,2m$
|
||||
1,2m$
|
||||
$m0
|
||||
$m0
|
||||
2,3m1
|
||||
2,3m3
|
||||
w \m.o
|
||||
EOT
|
|
@ -0,0 +1,5 @@
|
|||
line5
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
|
@ -0,0 +1,5 @@
|
|||
line5
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
|
@ -0,0 +1,7 @@
|
|||
1,2m$
|
||||
1,2m$
|
||||
1,2m$
|
||||
$m0
|
||||
$m0
|
||||
2,3m1
|
||||
2,3m3
|
|
@ -0,0 +1,37 @@
|
|||
#!/bin/sh -
|
||||
# This script generates ed test scripts (.ed) from .t files
|
||||
|
||||
PATH="/bin:/usr/bin:/usr/local/bin/:."
|
||||
[ X"$ED" = X ] && ED="../ed"
|
||||
|
||||
for i in *.t; do
|
||||
# base=${i%.*}
|
||||
base=`echo $i | sed 's/\..*/'`
|
||||
(
|
||||
echo "#!/bin/sh -"
|
||||
echo "$ED - <<\EOT"
|
||||
echo "r \\$base.d"
|
||||
cat $i
|
||||
echo "w \\$base.o"
|
||||
echo EOT
|
||||
) >$base.ed
|
||||
chmod +x $base.ed
|
||||
# The following is pretty ugly and not appropriate use of ed
|
||||
# but the point is that it can be done...
|
||||
# base=`$ED - <<-EOF
|
||||
# r !echo $i
|
||||
# s/\..*
|
||||
# EOF`
|
||||
# $ED - <<-EOF
|
||||
# a
|
||||
# #!/bin/sh -
|
||||
# $ED - <<\EOT
|
||||
# r \\$base.d
|
||||
# w \\$base.o
|
||||
# EOT
|
||||
# .
|
||||
# -2r \\$i
|
||||
# w \\$base.ed
|
||||
# !chmod +x $base.ed
|
||||
# EOF
|
||||
done
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \n.d
|
||||
w \n.o
|
||||
EOT
|
|
@ -0,0 +1,5 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \p.d
|
||||
w \p.o
|
||||
EOT
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,8 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \r1.d
|
||||
1;r !echo hello world
|
||||
1
|
||||
r !echo hello world
|
||||
w \r1.o
|
||||
EOT
|
|
@ -0,0 +1,7 @@
|
|||
line 1
|
||||
hello world
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
hello world
|
|
@ -0,0 +1,7 @@
|
|||
line 1
|
||||
hello world
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
hello world
|
|
@ -0,0 +1,3 @@
|
|||
1;r !echo hello world
|
||||
1
|
||||
r !echo hello world
|
|
@ -0,0 +1,5 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh -
|
||||
../ed - <<\EOT
|
||||
r \r2.d
|
||||
r
|
||||
w \r2.o
|
||||
EOT
|
|
@ -0,0 +1,10 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
|
@ -0,0 +1,10 @@
|
|||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
||||
line 1
|
||||
line 2
|
||||
line 3
|
||||
line 4
|
||||
line5
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue