home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / misc / volume37 / ed / part02 < prev    next >
Encoding:
Text File  |  1993-05-31  |  54.3 KB  |  2,157 lines

  1. Newsgroups: comp.sources.misc
  2. From: alm@netcom.com (Andrew Moore)
  3. Subject: v37i096:  ed - POSIX-compliant line editor, Part02/03
  4. Message-ID: <1993May31.025426.13079@sparky.imd.sterling.com>
  5. X-Md4-Signature: 5ccb7665ff184c59d6360790bd57f01b
  6. Sender: kent@sparky.imd.sterling.com (Kent Landfield)
  7. Organization: Sterling Software
  8. Date: Mon, 31 May 1993 02:54:26 GMT
  9. Approved: kent@sparky.imd.sterling.com
  10.  
  11. Submitted-by: alm@netcom.com (Andrew Moore)
  12. Posting-number: Volume 37, Issue 96
  13. Archive-name: ed/part02
  14. Environment: POSIX, sun, linux, bsd
  15.  
  16. #! /bin/sh
  17. # This is a shell archive.  Remove anything before this line, then feed it
  18. # into a shell via "sh file" or similar.  To overwrite existing files,
  19. # type "sh file -c".
  20. # Contents:  buf.c cbc.c ed.1 ed.h re.c
  21. # Wrapped by kent@sparky on Sun May 30 21:42:59 1993
  22. PATH=/bin:/usr/bin:/usr/ucb:/usr/local/bin:/usr/lbin ; export PATH
  23. echo If this archive is complete, you will see the following message:
  24. echo '          "shar: End of archive 2 (of 3)."'
  25. if test -f 'buf.c' -a "${1}" != "-c" ; then 
  26.   echo shar: Will not clobber existing file \"'buf.c'\"
  27. else
  28.   echo shar: Extracting \"'buf.c'\" \(6064 characters\)
  29.   sed "s/^X//" >'buf.c' <<'END_OF_FILE'
  30. X/* buf.c: This file contains the scratch-file buffer rountines for the
  31. X   ed line editor. */
  32. X/*-
  33. X * Copyright (c) 1992 The Regents of the University of California.
  34. X * All rights reserved.
  35. X *
  36. X * This code is derived from software contributed to Berkeley by
  37. X * Rodney Ruddock of the University of Guelph.
  38. X *
  39. X * Redistribution and use in source and binary forms, with or without
  40. X * modification, are permitted provided that the following conditions
  41. X * are met:
  42. X * 1. Redistributions of source code must retain the above copyright
  43. X *    notice, this list of conditions and the following disclaimer.
  44. X * 2. Redistributions in binary form must reproduce the above copyright
  45. X *    notice, this list of conditions and the following disclaimer in the
  46. X *    documentation and/or other materials provided with the distribution.
  47. X * 3. All advertising materials mentioning features or use of this software
  48. X *    must display the following acknowledgement:
  49. X *    This product includes software developed by the University of
  50. X *    California, Berkeley and its contributors.
  51. X * 4. Neither the name of the University nor the names of its contributors
  52. X *    may be used to endorse or promote products derived from this software
  53. X *    without specific prior written permission.
  54. X *
  55. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  56. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  57. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  58. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  59. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  60. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  61. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  62. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  63. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  64. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  65. X * SUCH DAMAGE.
  66. X */
  67. X
  68. X#ifndef lint
  69. Xstatic char sccsid[] = "@(#)buf.c    5.5 (Berkeley) 3/28/93";
  70. X#endif /* not lint */
  71. X
  72. X#include <stdio.h>
  73. X#include <stdlib.h>
  74. X#include <string.h>
  75. X#include <sys/file.h>
  76. X#include <unistd.h>
  77. X
  78. X#include "ed.h"
  79. X
  80. Xextern char errmsg[];
  81. Xextern line_t line0;
  82. X
  83. XFILE *sfp;                /* scratch file pointer */
  84. Xchar *sfbuf = NULL;            /* scratch file input buffer */
  85. Xint sfbufsz = 0;            /* scratch file input buffer size */
  86. Xoff_t sfseek;                /* scratch file position */
  87. Xint seek_write;                /* seek before writing */
  88. X
  89. X/* gettxt: get a line of text from the scratch file; return pointer
  90. X   to the text */
  91. Xchar *
  92. Xgettxt(lp)
  93. X    line_t *lp;
  94. X{
  95. X    int len, ct;
  96. X
  97. X    if (lp == &line0)
  98. X        return NULL;
  99. X    seek_write = 1;                /* force seek on write */
  100. X    /* out of position */
  101. X    if (sfseek != lp->seek) {
  102. X        sfseek = lp->seek;
  103. X        if (fseek(sfp, sfseek, SEEK_SET) < 0) {
  104. X            fprintf(stderr, "%s\n", strerror(errno));
  105. X            sprintf(errmsg, "cannot seek temp file");
  106. X            return NULL;
  107. X        }
  108. X    }
  109. X    len = lp->len & ~ACTV;
  110. X    CKBUF(sfbuf, sfbufsz, len + 1, NULL);
  111. X    if ((ct = fread(sfbuf, sizeof(char), len, sfp)) <  0 || ct != len) {
  112. X        fprintf(stderr, "%s\n", strerror(errno));
  113. X        sprintf(errmsg, "cannot read temp file");
  114. X        return NULL;
  115. X    }
  116. X    sfseek += len;                /* update file position */
  117. X    sfbuf[len] = '\0';
  118. X    return sfbuf;
  119. X}
  120. X
  121. X
  122. Xextern long curln;
  123. Xextern long lastln;
  124. X
  125. X/* puttxt: write a line of text to the scratch file and add a line node
  126. X   to the editor buffer;  return a pointer to the end of the text */
  127. Xchar *
  128. Xputtxt(cs)
  129. X    char *cs;
  130. X{
  131. X    line_t *lp;
  132. X    int len, ct;
  133. X    char *s;
  134. X
  135. X    if ((lp = (line_t *) malloc(sizeof(line_t))) == NULL) {
  136. X        fprintf(stderr, "%s\n", strerror(errno));
  137. X        sprintf(errmsg, "out of memory");
  138. X        return NULL;
  139. X    }
  140. X    /* assert: cs is '\n' terminated */
  141. X    for (s = cs; *s != '\n'; s++)
  142. X        ;
  143. X    if (s - cs >= LINECHARS) {
  144. X        sprintf(errmsg, "line too long");
  145. X        return NULL;
  146. X    }
  147. X    len = (s - cs) & ~ACTV;
  148. X    /* out of position */
  149. X    if (seek_write) {
  150. X        if (fseek(sfp, 0L, SEEK_END) < 0) {
  151. X            fprintf(stderr, "%s\n", strerror(errno));
  152. X            sprintf(errmsg, "cannot seek temp file");
  153. X            return NULL;
  154. X        }
  155. X        sfseek = ftell(sfp);
  156. X        seek_write = 0;
  157. X    }
  158. X    /* assert: spl1() */
  159. X    if ((ct = fwrite(cs, sizeof(char), len, sfp)) < 0 || ct != len) {
  160. X        sfseek = -1;
  161. X        fprintf(stderr, "%s\n", strerror(errno));
  162. X        sprintf(errmsg, "cannot write temp file");
  163. X        return NULL;
  164. X    }
  165. X    lp->len = len;
  166. X    lp->seek  = sfseek;
  167. X    lpqueue(lp);
  168. X    sfseek += len;            /* update file position */
  169. X    return ++s;
  170. X}
  171. X
  172. X
  173. X/* lpqueue: add a line node in the editor buffer after the current line */
  174. Xvoid
  175. Xlpqueue(lp)
  176. X    line_t *lp;
  177. X{
  178. X    line_t *cp;
  179. X
  180. X    cp = getlp(curln);                /* this getlp last! */
  181. X    insqueue(lp, cp);
  182. X    lastln++;
  183. X    curln++;
  184. X}
  185. X
  186. X
  187. X/* getaddr: return line number of pointer */
  188. Xlong
  189. Xgetaddr(lp)
  190. X    line_t *lp;
  191. X{
  192. X    line_t *cp = &line0;
  193. X    long n = 0;
  194. X
  195. X    while (cp != lp && (cp = cp->next) != &line0)
  196. X        n++;
  197. X    return (cp != &line0) ? n : 0;
  198. X}
  199. X
  200. X
  201. X/* getlp: return pointer to a line node in the editor buffer */
  202. Xline_t *
  203. Xgetlp(n)
  204. X    long n;
  205. X{
  206. X    static line_t *lp = &line0;
  207. X    static long on = 0;
  208. X
  209. X    spl1();
  210. X    if (n > on)
  211. X        if (n <= (on + lastln) >> 1)
  212. X            for (; on < n; on++)
  213. X                lp = lp->next;
  214. X        else {
  215. X            lp = line0.prev;
  216. X            for (on = lastln; on > n; on--)
  217. X                lp = lp->prev;
  218. X        }
  219. X    else
  220. X        if (n >= on >> 1)
  221. X            for (; on > n; on--)
  222. X                lp = lp->prev;
  223. X        else {
  224. X            lp = &line0;
  225. X            for (on = 0; on < n; on++)
  226. X                lp = lp->next;
  227. X        }
  228. X    spl0();
  229. X    return lp;
  230. X}
  231. X
  232. X
  233. Xchar sfn[15] = "";                /* scratch file name */
  234. X
  235. X/* sbopen: open scratch file */
  236. Xsbopen()
  237. X{
  238. X    strcpy(sfn, "/tmp/ed.XXXXXX");
  239. X    if (mktemp(sfn) == NULL || (sfp = fopen(sfn, "w+")) == NULL) {
  240. X        fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
  241. X        sprintf(errmsg, "cannot open temp file");
  242. X        return ERR;
  243. X    }
  244. X    return 0;
  245. X}
  246. X
  247. X
  248. X/* sbclose: close scratch file */
  249. Xsbclose()
  250. X{
  251. X    if (sfp) {
  252. X        if (fclose(sfp) < 0) {
  253. X            fprintf(stderr, "%s: %s\n", sfn, strerror(errno));
  254. X            sprintf(errmsg, "cannot close temp file");
  255. X            return ERR;
  256. X        }
  257. X        sfp = NULL;
  258. X        unlink(sfn);
  259. X    }
  260. X    sfseek = seek_write = 0;
  261. X    return 0;
  262. X}
  263. X
  264. X
  265. X/* quit: remove scratch file and exit */
  266. Xvoid
  267. Xquit(n)
  268. X    int n;
  269. X{
  270. X    if (sfp) {
  271. X        fclose(sfp);
  272. X        unlink(sfn);
  273. X    }
  274. X    exit(n);
  275. X}
  276. END_OF_FILE
  277.   if test 6064 -ne `wc -c <'buf.c'`; then
  278.     echo shar: \"'buf.c'\" unpacked with wrong size!
  279.   fi
  280.   # end of 'buf.c'
  281. fi
  282. if test -f 'cbc.c' -a "${1}" != "-c" ; then 
  283.   echo shar: Will not clobber existing file \"'cbc.c'\"
  284. else
  285.   echo shar: Extracting \"'cbc.c'\" \(11393 characters\)
  286.   sed "s/^X//" >'cbc.c' <<'END_OF_FILE'
  287. X/* cbc.c: This file contains the encryption routines for the ed line editor */
  288. X/*-
  289. X * Copyright (c) 1991 The Regents of the University of California.
  290. X * All rights reserved.
  291. X *
  292. X * This code is derived from software contributed to Berkeley by
  293. X * Matt Bishop of Dartmouth College.
  294. X *
  295. X * The United States Government has rights in this work pursuant
  296. X * to contract no. NAG 2-680 between the National Aeronautics and
  297. X * Space Administration and Dartmouth College.
  298. X *
  299. X * Redistribution and use in source and binary forms, with or without
  300. X * modification, are permitted provided that the following conditions
  301. X * are met:
  302. X * 1. Redistributions of source code must retain the above copyright
  303. X *    notice, this list of conditions and the following disclaimer.
  304. X * 2. Redistributions in binary form must reproduce the above copyright
  305. X *    notice, this list of conditions and the following disclaimer in the
  306. X *    documentation and/or other materials provided with the distribution.
  307. X * 3. All advertising materials mentioning features or use of this software
  308. X *    must display the following acknowledgement:
  309. X *    This product includes software developed by the University of
  310. X *    California, Berkeley and its contributors.
  311. X * 4. Neither the name of the University nor the names of its contributors
  312. X *    may be used to endorse or promote products derived from this software
  313. X *    without specific prior written permission.
  314. X *
  315. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  316. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  317. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  318. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  319. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  320. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  321. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  322. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  323. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  324. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  325. X * SUCH DAMAGE.
  326. X */
  327. X
  328. X#ifndef lint
  329. Xstatic char sccsid[] = "@(#)cbc.c    5.5 (Berkeley) 6/27/91";
  330. X#endif /* not lint */
  331. X
  332. X/* Author: Matt Bishop
  333. X *       Department of Mathematics and Computer Science
  334. X *       Dartmouth College
  335. X *       Hanover, NH  03755
  336. X * Email:  Matt.Bishop@dartmouth.edu
  337. X *       ...!decvax!dartvax!Matt.Bishop
  338. X *
  339. X * See Technical Report PCS-TR91-158, Department of Mathematics and Computer
  340. X * Science, Dartmouth College, for a detailed description of the implemen-
  341. X * tation and differences between it and Sun's.  The DES is described in
  342. X * FIPS PUB 46, and the modes in FIPS PUB 81 (see either the manual page
  343. X * or the technical report for a complete reference).
  344. X */
  345. X
  346. X#include <errno.h>
  347. X#include <pwd.h>
  348. X#include <unistd.h>
  349. X#include <stdio.h>
  350. X#include <ctype.h>
  351. X#include <stdlib.h>
  352. X#include <string.h>
  353. X#include <sys/types.h>
  354. X
  355. X#include "ed.h"
  356. X
  357. X/*
  358. X * Define a divisor for rand() that yields a uniform distribution in the
  359. X * range 0-255.
  360. X */
  361. X#define    RAND_DIV (((unsigned) RAND_MAX + 1) >> 8)
  362. X
  363. X/*
  364. X * BSD and System V systems offer special library calls that do
  365. X * block moves and fills, so if possible we take advantage of them
  366. X */
  367. X#define    MEMCPY(dest,src,len)    memcpy((dest),(src),(len))
  368. X#define    MEMZERO(dest,len)    memset((dest), 0, (len))
  369. X
  370. X/* Hide the calls to the primitive encryption routines. */
  371. X#define    DES_KEY(buf) \
  372. X    if (des_setkey(buf)) \
  373. X        err("des_setkey");
  374. X#define    DES_XFORM(buf) \
  375. X    if (des_cipher(buf, buf, 0L, (inverse ? -1 : 1))) \
  376. X        err("des_cipher");
  377. X
  378. X/*
  379. X * read/write - no error checking
  380. X */
  381. X#define    READ(buf, n, fp)    fread(buf, sizeof(char), n, fp)
  382. X#define WRITE(buf, n, fp)    fwrite(buf, sizeof(char), n, fp)
  383. X
  384. X/*
  385. X * some things to make references easier
  386. X */
  387. Xtypedef char Desbuf[8];
  388. X#define    CHAR(x,i)    (x[i])
  389. X#define    UCHAR(x,i)    (x[i])
  390. X#define    BUFFER(x)    (x)
  391. X#define    UBUFFER(x)    (x)
  392. X
  393. X/*
  394. X * global variables and related macros
  395. X */
  396. X
  397. Xenum {                     /* encrypt, decrypt, authenticate */
  398. X    MODE_ENCRYPT, MODE_DECRYPT, MODE_AUTHENTICATE
  399. X} mode = MODE_ENCRYPT;
  400. X
  401. XDesbuf ivec;                /* initialization vector */
  402. XDesbuf pvec;                /* padding vector */
  403. Xchar bits[] = {                /* used to extract bits from a char */
  404. X    '\200', '\100', '\040', '\020', '\010', '\004', '\002', '\001'
  405. X};
  406. Xint pflag;                /* 1 to preserve parity bits */
  407. X
  408. Xchar des_buf[8];        /* shared buffer for desgetc/desputc */
  409. Xint des_ct = 0;            /* count for desgetc/desputc */
  410. Xint des_n = 0;            /* index for desputc/desgetc */
  411. X
  412. X
  413. X/* desinit: initialize DES */
  414. Xvoid
  415. Xdesinit()
  416. X{
  417. X#ifdef DES
  418. X    int i;
  419. X
  420. X    des_ct = des_n = 0;
  421. X
  422. X    /* initialize the initialization vctor */
  423. X    MEMZERO(ivec, 8);
  424. X
  425. X    /* intialize the padding vector */
  426. X    srand((unsigned) time((time_t *) 0));
  427. X    for (i = 0; i < 8; i++)
  428. X        CHAR(pvec, i) = (char) (rand()/RAND_DIV);
  429. X#endif
  430. X}
  431. X
  432. X
  433. X/* desgetc: return next char in an encrypted file */
  434. Xdesgetc(fp)
  435. X    FILE *fp;
  436. X{
  437. X#ifdef DES
  438. X    if (des_n >= des_ct) {
  439. X        des_n = 0;
  440. X        des_ct = cbcdec(des_buf, fp);
  441. X    }
  442. X    return (des_ct > 0) ? des_buf[des_n++] : EOF;
  443. X#endif
  444. X}
  445. X
  446. X
  447. X/* desputc: write a char to an encrypted file; return char written */
  448. Xdesputc(c, fp)
  449. X    int c;
  450. X    FILE *fp;
  451. X{
  452. X#ifdef DES
  453. X    if (des_n == sizeof des_buf) {
  454. X        des_ct = cbcenc(des_buf, des_n, fp);
  455. X        des_n = 0;
  456. X    }
  457. X    return (des_ct >= 0) ? (des_buf[des_n++] = c) : EOF;
  458. X#endif
  459. X}
  460. X
  461. X
  462. X/* desflush: flush an encrypted file's output; return status */
  463. Xdesflush(fp)
  464. X    FILE *fp;
  465. X{
  466. X#ifdef DES
  467. X    if (des_n == sizeof des_buf) {
  468. X        des_ct = cbcenc(des_buf, des_n, fp);
  469. X        des_n = 0;
  470. X    }
  471. X    return (des_ct >= 0 && cbcenc(des_buf, des_n, fp) >= 0) ? 0 : EOF;
  472. X#endif
  473. X}
  474. X
  475. X#ifdef DES
  476. X/*
  477. X * get keyword from tty or stdin
  478. X */
  479. Xgetkey()
  480. X{
  481. X    register char *p;        /* used to obtain the key */
  482. X    Desbuf msgbuf;            /* I/O buffer */
  483. X
  484. X    /*
  485. X     * get the key
  486. X     */
  487. X    if (*(p = getpass("Enter key: "))) {
  488. X
  489. X        /*
  490. X         * copy it, nul-padded, into the key area
  491. X         */
  492. X        cvtkey(BUFFER(msgbuf), p);
  493. X        MEMZERO(p, _PASSWORD_LEN);
  494. X        makekey(msgbuf);
  495. X        MEMZERO(msgbuf, sizeof msgbuf);
  496. X        return 1;
  497. X    }
  498. X    return 0;
  499. X}
  500. X
  501. X
  502. Xextern char errmsg[];
  503. X
  504. X/*
  505. X * print a warning message and, possibly, terminate
  506. X */
  507. Xvoid
  508. Xerr(s)
  509. X    char *s;        /* the message */
  510. X{
  511. X    (void)sprintf(errmsg, "%s", s ? s : strerror(errno));
  512. X}
  513. X
  514. X/*
  515. X * map a hex character to an integer
  516. X */
  517. Xtobinhex(c, radix)
  518. X    int c;            /* char to be converted */
  519. X    int radix;        /* base (2 to 16) */
  520. X{
  521. X    switch(c) {
  522. X    case '0':        return(0x0);
  523. X    case '1':        return(0x1);
  524. X    case '2':        return(radix > 2 ? 0x2 : -1);
  525. X    case '3':        return(radix > 3 ? 0x3 : -1);
  526. X    case '4':        return(radix > 4 ? 0x4 : -1);
  527. X    case '5':        return(radix > 5 ? 0x5 : -1);
  528. X    case '6':        return(radix > 6 ? 0x6 : -1);
  529. X    case '7':        return(radix > 7 ? 0x7 : -1);
  530. X    case '8':        return(radix > 8 ? 0x8 : -1);
  531. X    case '9':        return(radix > 9 ? 0x9 : -1);
  532. X    case 'A': case 'a':    return(radix > 10 ? 0xa : -1);
  533. X    case 'B': case 'b':    return(radix > 11 ? 0xb : -1);
  534. X    case 'C': case 'c':    return(radix > 12 ? 0xc : -1);
  535. X    case 'D': case 'd':    return(radix > 13 ? 0xd : -1);
  536. X    case 'E': case 'e':    return(radix > 14 ? 0xe : -1);
  537. X    case 'F': case 'f':    return(radix > 15 ? 0xf : -1);
  538. X    }
  539. X    /*
  540. X     * invalid character
  541. X     */
  542. X    return(-1);
  543. X}
  544. X
  545. X/*
  546. X * convert the key to a bit pattern
  547. X */
  548. Xvoid
  549. Xcvtkey(obuf, ibuf)
  550. X    char *obuf;            /* bit pattern */
  551. X    char *ibuf;            /* the key itself */
  552. X{
  553. X    register int i, j;        /* counter in a for loop */
  554. X    int nbuf[64];            /* used for hex/key translation */
  555. X
  556. X    /*
  557. X     * leading '0x' or '0X' == hex key
  558. X     */
  559. X    if (ibuf[0] == '0' && (ibuf[1] == 'x' || ibuf[1] == 'X')) {
  560. X        ibuf = &ibuf[2];
  561. X        /*
  562. X         * now translate it, bombing on any illegal hex digit
  563. X         */
  564. X        for (i = 0; ibuf[i] && i < 16; i++)
  565. X            if ((nbuf[i] = tobinhex((int) ibuf[i], 16)) == -1)
  566. X                err("bad hex digit in key");
  567. X        while (i < 16)
  568. X            nbuf[i++] = 0;
  569. X        for (i = 0; i < 8; i++)
  570. X            obuf[i] =
  571. X                ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
  572. X        /* preserve parity bits */
  573. X        pflag = 1;
  574. X        return;
  575. X    }
  576. X    /*
  577. X     * leading '0b' or '0B' == binary key
  578. X     */
  579. X    if (ibuf[0] == '0' && (ibuf[1] == 'b' || ibuf[1] == 'B')) {
  580. X        ibuf = &ibuf[2];
  581. X        /*
  582. X         * now translate it, bombing on any illegal binary digit
  583. X         */
  584. X        for (i = 0; ibuf[i] && i < 16; i++)
  585. X            if ((nbuf[i] = tobinhex((int) ibuf[i], 2)) == -1)
  586. X                err("bad binary digit in key");
  587. X        while (i < 64)
  588. X            nbuf[i++] = 0;
  589. X        for (i = 0; i < 8; i++)
  590. X            for (j = 0; j < 8; j++)
  591. X                obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
  592. X        /* preserve parity bits */
  593. X        pflag = 1;
  594. X        return;
  595. X    }
  596. X    /*
  597. X     * no special leader -- ASCII
  598. X     */
  599. X    (void)strncpy(obuf, ibuf, 8);
  600. X}
  601. X
  602. X/*****************
  603. X * DES FUNCTIONS *
  604. X *****************/
  605. X/*
  606. X * This sets the DES key and (if you're using the deszip version)
  607. X * the direction of the transformation.  This uses the Sun
  608. X * to map the 64-bit key onto the 56 bits that the key schedule
  609. X * generation routines use: the old way, which just uses the user-
  610. X * supplied 64 bits as is, and the new way, which resets the parity
  611. X * bit to be the same as the low-order bit in each character.  The
  612. X * new way generates a greater variety of key schedules, since many
  613. X * systems set the parity (high) bit of each character to 0, and the
  614. X * DES ignores the low order bit of each character.
  615. X */
  616. Xvoid
  617. Xmakekey(buf)
  618. X    Desbuf buf;                /* key block */
  619. X{
  620. X    register int i, j;            /* counter in a for loop */
  621. X    register int par;            /* parity counter */
  622. X
  623. X    /*
  624. X     * if the parity is not preserved, flip it
  625. X     */
  626. X    if (!pflag) {
  627. X        for (i = 0; i < 8; i++) {
  628. X            par = 0;
  629. X            for (j = 1; j < 8; j++)
  630. X                if ((bits[j]&UCHAR(buf, i)) != 0)
  631. X                    par++;
  632. X            if ((par&01) == 01)
  633. X                UCHAR(buf, i) = UCHAR(buf, i)&0177;
  634. X            else
  635. X                UCHAR(buf, i) = (UCHAR(buf, i)&0177)|0200;
  636. X        }
  637. X    }
  638. X
  639. X    DES_KEY(UBUFFER(buf));
  640. X}
  641. X
  642. X
  643. X/*
  644. X * This encrypts using the Cipher Block Chaining mode of DES
  645. X */
  646. Xcbcenc(msgbuf, n, fp)
  647. X    char *msgbuf;
  648. X    int n;
  649. X    FILE *fp;
  650. X{
  651. X    int inverse = 0;    /* 0 to encrypt, 1 to decrypt */
  652. X
  653. X    /*
  654. X     * do the transformation
  655. X     */
  656. X    if (n == 8) {
  657. X        for (n = 0; n < 8; n++)
  658. X            CHAR(msgbuf, n) ^= CHAR(ivec, n);
  659. X        DES_XFORM(UBUFFER(msgbuf));
  660. X        MEMCPY(BUFFER(ivec), BUFFER(msgbuf), 8);
  661. X        return WRITE(BUFFER(msgbuf), 8, fp);
  662. X    }
  663. X    /*
  664. X     * at EOF or last block -- in either case, the last byte contains
  665. X     * the character representation of the number of bytes in it
  666. X     */
  667. X/*
  668. X    MEMZERO(msgbuf +  n, 8 - n);
  669. X*/
  670. X    /*
  671. X     *  Pad the last block randomly
  672. X     */
  673. X    (void)MEMCPY(BUFFER(msgbuf + n), BUFFER(pvec), 8 - n);
  674. X    CHAR(msgbuf, 7) = n;
  675. X    for (n = 0; n < 8; n++)
  676. X        CHAR(msgbuf, n) ^= CHAR(ivec, n);
  677. X    DES_XFORM(UBUFFER(msgbuf));
  678. X    return WRITE(BUFFER(msgbuf), 8, fp);
  679. X}
  680. X
  681. X/*
  682. X * This decrypts using the Cipher Block Chaining mode of DES
  683. X */
  684. Xcbcdec(msgbuf, fp)
  685. X    char *msgbuf;        /* I/O buffer */
  686. X    FILE *fp;            /* input file descriptor */
  687. X{
  688. X    Desbuf ibuf;    /* temp buffer for initialization vector */
  689. X    register int n;        /* number of bytes actually read */
  690. X    register int c;        /* used to test for EOF */
  691. X    int inverse = 1;    /* 0 to encrypt, 1 to decrypt */
  692. X
  693. X    if ((n = READ(BUFFER(msgbuf), 8, fp)) == 8) {
  694. X        /*
  695. X         * do the transformation
  696. X         */
  697. X        MEMCPY(BUFFER(ibuf), BUFFER(msgbuf), 8);
  698. X        DES_XFORM(UBUFFER(msgbuf));
  699. X        for (c = 0; c < 8; c++)
  700. X            UCHAR(msgbuf, c) ^= UCHAR(ivec, c);
  701. X        MEMCPY(BUFFER(ivec), BUFFER(ibuf), 8);
  702. X        /*
  703. X         * if the last one, handle it specially
  704. X         */
  705. X        if ((c = fgetc(fp)) == EOF) {
  706. X            n = CHAR(msgbuf, 7);
  707. X            if (n < 0 || n > 7) {
  708. X                err("decryption failed (block corrupted)");
  709. X                return EOF;
  710. X            }
  711. X        } else
  712. X            (void)ungetc(c, fp);
  713. X        return n;
  714. X    }
  715. X    if (n > 0)
  716. X        err("decryption failed (incomplete block)");
  717. X    else if (n < 0)
  718. X        err("cannot read file");
  719. X    return EOF;
  720. X}
  721. X#endif    /* DES */
  722. END_OF_FILE
  723.   if test 11393 -ne `wc -c <'cbc.c'`; then
  724.     echo shar: \"'cbc.c'\" unpacked with wrong size!
  725.   fi
  726.   # end of 'cbc.c'
  727. fi
  728. if test -f 'ed.1' -a "${1}" != "-c" ; then 
  729.   echo shar: Will not clobber existing file \"'ed.1'\"
  730. else
  731.   echo shar: Extracting \"'ed.1'\" \(20771 characters\)
  732.   sed "s/^X//" >'ed.1' <<'END_OF_FILE'
  733. X.TH ED 1 "21 May 1993"
  734. X.SH NAME
  735. Xed, red \- text editor
  736. X.SH SYNOPSIS
  737. Xed [-] [-sx] [-p \fIstring\fR] [\fIfile\fR]
  738. X.LP
  739. Xred [-] [-sx] [-p \fIstring\fR] [\fIfile\fR]
  740. X.SH DESCRIPTION
  741. X.B ed
  742. Xis a line-oriented text editor.
  743. XIt is used to create, display, modify and otherwise manipulate text
  744. Xfiles.
  745. X.B red
  746. Xis a restricted
  747. X.BR ed :
  748. Xit can only edit files in the current
  749. Xdirectory and cannot execute shell commands.
  750. X
  751. XIf invoked with a
  752. X.I file
  753. Xargument, then a copy of
  754. X.I file
  755. Xis read into the editor's buffer.
  756. XChanges are made to this copy and not directly to
  757. X.I file
  758. Xitself.
  759. XUpon quitting
  760. X.BR ed ,
  761. Xany changes not explicitly saved  with a
  762. X.I `w'
  763. Xcommand are lost.
  764. X
  765. XEditing is done in two distinct modes:
  766. X.I command
  767. Xand
  768. X.IR input .
  769. XWhen first invoked,
  770. X.B ed
  771. Xis in command mode.
  772. XIn this mode commands are read from the standard input and
  773. Xexecuted to manipulate the contents of the editor buffer.
  774. XA typical command might look like:
  775. X.sp
  776. X.RS
  777. X,s/\fIold\fR/\fInew\fR/g
  778. X.RE
  779. X.sp
  780. Xwhich replaces all occurences of the string
  781. X.I old
  782. Xwith
  783. X.IR new .
  784. X
  785. XWhen an input command, such as
  786. X.I `a'
  787. X(append),
  788. X.I `i'
  789. X(insert) or
  790. X.I `c'
  791. X(change), is given,
  792. X.B ed
  793. Xenters input mode.  This is the primary means
  794. Xof adding text to a file.
  795. XIn this mode, no commands are available;
  796. Xinstead, the standard input is written
  797. Xdirectly to the editor buffer.  Lines consist of text up to and
  798. Xincluding a
  799. X.IR newline
  800. Xcharacter.
  801. XInput mode is terminated by
  802. Xentering a single period  (\fI.\fR) on a line.
  803. X
  804. XAll
  805. X.B ed
  806. Xcommands operate on whole lines or ranges of lines; e.g.,
  807. Xthe
  808. X.I `d'
  809. Xcommand deletes lines; the
  810. X.I `m'
  811. Xcommand moves lines, and so on.
  812. XIt is possible to modify only a portion of a line by means of replacement,
  813. Xas in the example above.  However even here, the
  814. X.I `s'
  815. Xcommand is applied to whole lines at a time.
  816. X
  817. XIn general,
  818. X.B ed
  819. Xcommands consist of zero or more line addresses, followed by a single
  820. Xcharacter command and possibly additional parameters; i.e.,
  821. Xcommands have the structure:
  822. X.sp
  823. X.RS
  824. X.I [address [,address]]command[parameters]
  825. X.RE
  826. X.sp
  827. XThe address(es) indicate the line(s) to be affected by the command.
  828. XIf fewer addresses are given than the command accepts, then default
  829. Xaddresses are supplied.
  830. X
  831. X.SS OPTIONS
  832. X.TP 8
  833. X-s
  834. XSuppresses diagnostics. This should be used if
  835. X.BR ed 's
  836. Xstandard input is from a script.
  837. X
  838. X.TP 8
  839. X-x
  840. XPrompts for an encryption key to be used in subsequent reads and writes
  841. X(see the
  842. X.I `x'
  843. Xcommand).
  844. X
  845. X.TP 8
  846. X.RI \-p \ string
  847. XSpecifies a command prompt.  This may be toggled on and off with the
  848. X.I `P'
  849. Xcommand.
  850. X
  851. X.TP 8
  852. X.I file
  853. XSpecifies the name of a file to read.  If
  854. X.I file
  855. Xis prefixed with a
  856. Xbang (!), then it is interpreted as a shell command.  In this case,
  857. Xwhat is read is
  858. Xthe standard output of
  859. X.I file
  860. Xexecuted via
  861. X.IR sh (1).
  862. XTo read a file whose name begins with a bang, prefix the
  863. Xname with a backslash (\\).
  864. XThe default filename is set to
  865. X.I file
  866. Xonly if it is not prefixed with a bang.
  867. X
  868. X.SS LINE ADDRESSING
  869. XAn address represents the number of line in the buffer.
  870. X.B ed
  871. Xmaintains a
  872. X.I current address
  873. Xwhich is
  874. Xtypically supplied to commands as the default address when none is specified.
  875. XWhen a file is first read,  the current address is set to the last line
  876. Xof the file.  In general, the current address is set to the last line
  877. Xaffected by a command.
  878. X
  879. XA line address is
  880. Xconstructed from one of the bases in the list below, optionally followed
  881. Xby a numeric offset.  The offset may include any combination
  882. Xof digits, operators (i.e.,
  883. X.IR + ,
  884. X.I -
  885. Xand
  886. X.IR ^ )
  887. Xand whitespace.
  888. XAddresses are read from left to right, and their values are computed
  889. Xrelative to the current address.
  890. X
  891. XOne exception to the rule that addresses represent line numbers is the
  892. Xaddress
  893. X.I 0
  894. X(zero).
  895. XThis means "before the first line,"
  896. Xand is legal wherever it makes sense.
  897. X
  898. XAn address range is two addresses separated either by a comma or
  899. Xsemi-colon. The value of the first address in a range cannot exceed the
  900. Xvalue of the the second.  If an
  901. X.IR n- tuple
  902. Xof addresses is given where
  903. X.I n > 2,
  904. Xthen the corresponding range is determined by the last two addresses
  905. Xin the
  906. X.IR n- tuple.
  907. XIf only one address is expected, then the last
  908. Xaddress is used.
  909. X
  910. XEach address in a comma-delimited range is interpreted relative to the
  911. Xcurrent address.  In a semi-colon-delimited range, the first address is
  912. Xused to set the current address, and the second address is interpreted
  913. Xrelative to the first.
  914. X
  915. XThe following address symbols are recognized.
  916. X
  917. X.TP 8
  918. X\fR.\fR
  919. XThe current line (address) in the buffer.
  920. X
  921. X.TP 8
  922. X$
  923. XThe last line in the buffer.
  924. X
  925. X.TP 8
  926. Xn
  927. XThe
  928. X.IR n th,
  929. Xline in the buffer
  930. Xwhere
  931. X.I n
  932. Xis a number in the range
  933. X.I [0,$].
  934. X
  935. X.TP 8
  936. X- or ^
  937. XThe previous line.
  938. XThis is equivalent to
  939. X.I -1
  940. Xand may be repeated with cumulative effect.
  941. X
  942. X.TP 8
  943. X-\fIn\fR or ^\fIn\fR
  944. XThe
  945. X.IR n th
  946. Xprevious line, where
  947. X.I n
  948. Xis a non-negative number.
  949. X
  950. X.TP 8
  951. X+
  952. XThe
  953. Xnext line.
  954. XThis is equivalent to
  955. X.I +1
  956. Xand may be repeated with cumulative effect.
  957. X
  958. X.TP 8
  959. X+\fIn\fR or whitespace\fIn\fR
  960. XThe
  961. X.IR n th
  962. Xnext line, where
  963. X.I n
  964. Xis a non-negative number.
  965. X.I whitespace
  966. Xfollowed by a number
  967. X.I n
  968. Xis interpreted as
  969. X.IR +n .
  970. X
  971. X.TP 8
  972. X, \fRor\fB %
  973. XThe first through last lines in the buffer.  This is equivalent to
  974. Xthe address range
  975. X.I 1,$.
  976. X
  977. X.TP 8
  978. X;
  979. XThe
  980. Xcurrent through last lines in the buffer.  This is equivalent to
  981. Xthe address range
  982. X.I .,$.
  983. X
  984. X.TP 8
  985. X.RI / re/
  986. XThe
  987. Xnext line containing the regular expression
  988. X.IR re .
  989. XThe search wraps to the beginning of the buffer and continues down to the
  990. Xcurrent line, if necessary.
  991. X// repeats the last search.
  992. X
  993. X.TP 8
  994. X.RI ? re?
  995. XThe
  996. Xprevious line containing the regular expression
  997. X.IR re .
  998. XThe search wraps to the end of the buffer and continues up to the
  999. Xcurrent line, if necessary.
  1000. X?? repeats the last search.
  1001. X
  1002. X.TP 8
  1003. X.RI \' lc
  1004. XThe
  1005. Xline previously marked by a
  1006. X.I `k'
  1007. X(mark) command, where
  1008. X.I lc
  1009. Xis a lower case letter.
  1010. X
  1011. X.SS REGULAR EXPRESSIONS
  1012. XRegular expressions are patterns used in selecting text.
  1013. XFor example, the
  1014. X.B ed
  1015. Xcommand
  1016. X.sp
  1017. X.RS
  1018. Xg/\fIstring\fR/
  1019. X.RE
  1020. X.sp
  1021. Xprints all lines containing
  1022. X.IR string .
  1023. XRegular expressions are also
  1024. Xused by the
  1025. X.I `s'
  1026. Xcommand for selecting old text to be replaced with new.
  1027. X
  1028. XIn addition to a specifying string literals, regular expressions can
  1029. Xrepresent
  1030. Xclasses of strings.  Strings thus represented are said to be matched
  1031. Xby the corresponding regular expression.
  1032. XIf it is possible for a regular expression
  1033. Xto match several strings in a line, then the left-most longest match is
  1034. Xthe one selected.
  1035. X
  1036. XThe following symbols are used in constructing regular expressions:
  1037. X
  1038. X.TP 8
  1039. Xc
  1040. XAny character
  1041. X.I c
  1042. Xnot listed below, including `{', '}', `(', `)', `<' and `>',
  1043. Xmatches itself.
  1044. X
  1045. X.TP 8
  1046. X\fR\\\fIc\fR
  1047. XAny backslash-escaped character
  1048. X.IR c ,
  1049. Xexcept for `{', '}', `(', `)', `<' and `>',
  1050. Xmatches itself.
  1051. X
  1052. X.TP 8
  1053. X\fR.\fR
  1054. XMatches any single character.
  1055. X
  1056. X.TP 8
  1057. X.I [char-class]
  1058. XMatches any single character in
  1059. X.IR char-class .
  1060. XTo include a  `]'
  1061. Xin
  1062. X.IR char-class ,
  1063. Xit must be the first character.
  1064. XA range of characters may be specified by separating the end characters
  1065. Xof the range with a `-', e.g., `a-z' specifies the lower case characters.
  1066. XThe following literal expressions can also be used in
  1067. X.I char-class
  1068. Xto specify sets of characters:
  1069. X.sp
  1070. X\ \ [:alnum:]\ \ [:cntrl:]\ \ [:lower:]\ \ [:space:]
  1071. X.PD 0
  1072. X\ \ [:alpha:]\ \ [:digit:]\ \ [:print:]\ \ [:upper:]
  1073. X.PD 0
  1074. X\ \ [:blank:]\ \ [:graph:]\ \ [:punct:]\ \ [:xdigit:]
  1075. X.sp
  1076. XIf `-' appears as the first or last
  1077. Xcharacter of
  1078. X.IR char-class ,
  1079. Xthen it matches itself.
  1080. XAll other characters in
  1081. X.I char-class
  1082. Xmatch themselves.
  1083. X.sp
  1084. XPatterns in
  1085. X.I char-class
  1086. Xof the form:
  1087. X.sp
  1088. X\ \ [.\fIcol-elm\fR.] or,
  1089. X.PD 0
  1090. X\ \ [=\fIcol-elm\fR=]
  1091. X.sp
  1092. Xwhere
  1093. X.I col-elm
  1094. Xis a
  1095. X.I collating element
  1096. Xare interpreted according to
  1097. X.IR locale (5)
  1098. X(not currently supported).
  1099. XSee
  1100. X.IR regex (3)
  1101. Xfor an explanation of these constructs.
  1102. X
  1103. X.TP 8
  1104. X[^\fIchar-class\fR]
  1105. XMatches any single character, other than newline, not in
  1106. X.IR char-class .
  1107. X.IR char-class
  1108. Xis defined
  1109. Xas above.
  1110. X
  1111. X.TP 8
  1112. X^
  1113. XIf `^' is the first character of a regular expression, then it
  1114. Xanchors the regular expression to the beginning of a line.
  1115. XOtherwise, it matches itself.
  1116. X
  1117. X.TP 8
  1118. X$
  1119. XIf `$' is the last character of a regular expression, it
  1120. Xanchors the regular expression to the end of a line.
  1121. XOtherwise, it matches itself.
  1122. X
  1123. X.TP 8
  1124. X\fR\\<\fR
  1125. XAnchors the single character regular expression or subexpression
  1126. Ximmediately following it to the beginning of a word.
  1127. X(This may not be available)
  1128. X
  1129. X.TP 8
  1130. X\fR\\>\fR
  1131. XAnchors the single character regular expression or subexpression
  1132. Ximmediately following it to the end of a word.
  1133. X(This may not be available)
  1134. X
  1135. X.TP 8
  1136. X\fR\\(\fIre\fR\\)\fR
  1137. XDefines a subexpression
  1138. X.IR re .
  1139. XSubexpressions may be nested.
  1140. XA subsequent backreference of the form \fI`\\n'\fR, where
  1141. X.I n
  1142. Xis a number in the range [1,9], expands to the text matched by the
  1143. X.IR n th
  1144. Xsubexpression.
  1145. XFor example, the regular expression `\\(.*\\)\\1' matches any string
  1146. Xconsisting of identical adjacent substrings.
  1147. XSubexpressions are ordered relative to
  1148. Xtheir left delimiter.
  1149. X
  1150. X.TP 8
  1151. X*
  1152. XMatches the single character regular expression or subexpression
  1153. Ximmediately preceding it zero or more times.  If '*' is the first
  1154. Xcharacter of a regular expression or subexpression, then it matches
  1155. Xitself.  The `*' operator sometimes yields unexpected results.
  1156. XFor example, the regular expression `b*' matches the beginning of
  1157. Xthe string `abbb' (as opposed to the substring `bbb'), since a null match
  1158. Xis the only left-most match.
  1159. X
  1160. X.TP 8
  1161. X\fR\\{\fIn,m\fR\\}\fR or \fR\\{\fIn,\fR\\}\fR or \fR\\{\fIn\fR\\}\fR
  1162. XMatches the single character regular expression or subexpression
  1163. Ximmediately preceding it at least
  1164. X.I n
  1165. Xand at most
  1166. X.I m
  1167. Xtimes.
  1168. XIf
  1169. X.I m
  1170. Xis omitted, then it matches at least
  1171. X.I n
  1172. Xtimes.
  1173. XIf the comma is also omitted, then it matches exactly
  1174. X.I n
  1175. Xtimes.
  1176. X
  1177. X.LP
  1178. XAdditional regular expression operators may be defined depending on the
  1179. Xparticular
  1180. X.IR regex (3)
  1181. Ximplementation.
  1182. X
  1183. X.SS COMMANDS
  1184. XAll
  1185. X.B ed
  1186. Xcommands are single characters, though some require additonal parameters.
  1187. XIf a command's parameters extend over several lines, then
  1188. Xeach line except for the last
  1189. Xmust be terminated with a backslash (\\).
  1190. X
  1191. XIn general, at most one command is allowed per line.
  1192. XHowever, most commands accept a print suffix, which is any of
  1193. X.I `p'
  1194. X(print),
  1195. X.I `l'
  1196. X(list) ,
  1197. Xor
  1198. X.I `n'
  1199. X(enumerate),
  1200. Xto print the last line affected by the command.
  1201. X
  1202. XAn interrupt (typically ^C) has the effect of aborting the current command
  1203. Xand returning the editor to command mode.
  1204. X
  1205. X.B ed
  1206. Xrecognizes the following commands.  The commands are shown together with
  1207. Xthe default address or address range supplied if none is
  1208. Xspecified (in parenthesis).
  1209. X
  1210. X.TP 8
  1211. X(.)a
  1212. XAppends text to the buffer after the addressed line.
  1213. XText is entered in input mode.
  1214. XThe current address is set to last line entered.
  1215. X
  1216. X.TP 8
  1217. X(.,.)c
  1218. XChanges lines in the buffer.  The addressed lines are deleted
  1219. Xfrom the buffer, and text is appended in their place.
  1220. XText is entered in input mode.
  1221. XThe current address is set to last line entered.
  1222. X
  1223. X.TP 8
  1224. X(.,.)d
  1225. XDeletes the addressed lines from the buffer.
  1226. XIf there is a line after the deleted range, then the current address is set
  1227. Xto this line. Otherwise the current address is set to the line
  1228. Xbefore the deleted range.
  1229. X
  1230. X.TP 8
  1231. X.RI e \ file
  1232. XEdits
  1233. X.IR file ,
  1234. Xand sets the default filename.
  1235. XIf
  1236. X.I file
  1237. Xis not specified, then the  default filename is used.
  1238. XAny lines in the buffer are deleted before
  1239. Xthe new file is read.
  1240. XThe current address is set to the last line read.
  1241. X
  1242. X.TP 8
  1243. X.RI e \ !command
  1244. XEdits the standard output of
  1245. X.IR `!command' ,
  1246. Xexecuted as described below.
  1247. XThe default filename is unchanged.
  1248. XAny lines in the buffer are deleted before the output of
  1249. X.I command
  1250. Xis read.
  1251. XThe current address is set to the last line read.
  1252. X
  1253. X.TP 8
  1254. X.RI E \ name
  1255. XEdits
  1256. X.I name
  1257. Xunconditionally.
  1258. XThis is similar to the
  1259. X.I e
  1260. Xcommand,
  1261. Xexcept that unwritten changes are discarded without warning.
  1262. XThe current address is set to the last line read.
  1263. X
  1264. X.TP 8
  1265. X.RI f \ name
  1266. XSets the default filename to
  1267. X.IR name .
  1268. XIf
  1269. X.I name
  1270. Xis not specified, then the default unescaped filename is printed.
  1271. X
  1272. X.TP 8
  1273. X.RI (1,$)g /re/command-list
  1274. XApplies
  1275. X.I command-list
  1276. Xto each of the addressed lines matching a regular expression
  1277. X.IR re .
  1278. XThe current address is set to the
  1279. Xline currently matched before
  1280. X.I command-list
  1281. Xis executed.
  1282. XAt the end of the
  1283. X.I `g'
  1284. Xcommand, the current address is set to the last line affected by
  1285. X.IR command-list .
  1286. X
  1287. XEach command in
  1288. X.I command-list
  1289. Xmust be on a separate line,
  1290. Xand every line except for the last must be terminated by a backslash
  1291. X(\\).
  1292. XAny commands are allowed, except for
  1293. X.IR `g' ,
  1294. X.IR `G' ,
  1295. X.IR `v' ,
  1296. Xand
  1297. X.IR `V' .
  1298. X
  1299. X.TP 8
  1300. X.RI (1,$)G /re/
  1301. XInteractively edits the addressed lines matching a regular expression
  1302. X.IR re.
  1303. XFor each matching line,
  1304. Xthe line is printed,
  1305. Xthe current address is set,
  1306. Xand the user is prompted to enter a command list.
  1307. XAt the end of the
  1308. X.I `G'
  1309. Xcommand, the current address
  1310. Xis set to the last line affected by the command
  1311. Xlist.
  1312. X
  1313. XThe format of the command list is the same as that of the
  1314. X.I `g'
  1315. Xcommand.  A newline alone acts as a null command list.
  1316. XA single `&' repeats the last non-null command list.
  1317. X
  1318. X.TP 8
  1319. XH
  1320. XToggles the printing of error explanations.
  1321. XBy default, explanations are not printed.
  1322. XIt is recommended that ed scripts begin with this command to
  1323. Xaid in debugging.
  1324. X
  1325. X.TP 8
  1326. Xh
  1327. XPrints an explanation of the last error.
  1328. X
  1329. X.TP 8
  1330. X(.)i
  1331. XInserts text in the buffer before the current line.
  1332. XText is entered in input mode.
  1333. XThe current address is set to the last line entered.
  1334. X
  1335. X.TP 8
  1336. X(.,.+1)j
  1337. XJoins the addressed lines.  The addressed lines are
  1338. Xdeleted from the buffer and replaced by a single
  1339. Xline containing their joined text.
  1340. XThe current address is set to the resultant line.
  1341. X
  1342. X.TP 8
  1343. X.RI (.)k lc
  1344. XMarks a line with a lower case letter
  1345. X.IR lc .
  1346. XThe  line can then be addressed as
  1347. X.I 'lc
  1348. X(i.e., a single quote followed by
  1349. X.I lc
  1350. X) in subsequent commands.  The mark is not cleared until the line is
  1351. Xdeleted or otherwise modified.
  1352. X
  1353. X.TP 8
  1354. X(.,.)l
  1355. XPrints the addressed lines unambiguously.
  1356. XThe current address is set to the last line
  1357. Xprinted.
  1358. X
  1359. X.TP 8
  1360. X(.,.)m(.)
  1361. XMoves lines in the buffer.  The addressed lines are moved to after the
  1362. Xright-hand destination address, which may be the address
  1363. X.IR 0
  1364. X(zero).
  1365. XThe current address is set to the
  1366. Xlast line moved.
  1367. X
  1368. X.TP 8
  1369. X(.,.)n
  1370. XPrints the addressed lines along with
  1371. Xtheir line numbers.  The current address is set to the last line
  1372. Xprinted.
  1373. X
  1374. X.TP 8
  1375. X(.,.)p
  1376. XPrints the addressed lines. The current address is set to the last line
  1377. Xprinted.
  1378. X
  1379. X.TP 8
  1380. XP
  1381. XToggles the command prompt on and off.
  1382. XUnless a prompt was specified by with command-line option
  1383. X\fI-p string\fR, the command prompt is by default turned off.
  1384. X
  1385. X.TP 8
  1386. Xq
  1387. XQuits ed.
  1388. X
  1389. X.TP 8
  1390. XQ
  1391. XQuits ed unconditionally.
  1392. XThis is similar to the
  1393. X.I q
  1394. Xcommand,
  1395. Xexcept that unwritten changes are discarded without warning.
  1396. X
  1397. X.TP 8
  1398. X.RI ($)r \ file
  1399. XReads
  1400. X.I file
  1401. Xto after the addressed line.  If
  1402. X.I file
  1403. Xis not specified, then the default
  1404. Xfilename is used.  If there was no default filename prior to the command,
  1405. Xthen the default filename is set to
  1406. X.IR file .
  1407. XOtherwise, the default filename is unchanged.
  1408. XThe current address is set to the last line read.
  1409. X
  1410. X.TP 8
  1411. X.RI ($)r \ !command
  1412. XReads
  1413. Xto after the addressed line
  1414. Xthe standard output of
  1415. X.IR `!command' ,
  1416. Xexecuted as described below.
  1417. XThe default filename is unchanged.
  1418. XThe current address is set to the last line read.
  1419. X
  1420. X.HP
  1421. X.RI (.,.)s /re/replacement/
  1422. X.PD 0
  1423. X.HP
  1424. X.RI (.,.)s  /re/replacement/\fRg\fR
  1425. X.HP
  1426. X.RI (.,.)s  /re/replacement/n
  1427. X.br
  1428. XReplaces text in the addressed lines
  1429. Xmatching a regular expression
  1430. X.I re
  1431. Xwith
  1432. X.IR replacement .
  1433. XBy default, only the first match in each line is replaced.
  1434. XThe
  1435. X.I `g'
  1436. X(global) suffix causes every match to be replaced.
  1437. XThe
  1438. X.I `n'
  1439. Xsuffix, where
  1440. X.I n
  1441. Xis a postive number, causes only the
  1442. X.IR n th
  1443. Xmatch to be replaced.
  1444. XThe current address is set the last line affected.
  1445. X
  1446. X.I re
  1447. Xand
  1448. X.I replacement
  1449. Xmay be delimited by any character other than space and newline.
  1450. XIf one or two of the last delimiters is omitted, then the last line
  1451. Xaffected is printed as though the print suffix
  1452. X.I `p'
  1453. Xwere specified.
  1454. X
  1455. X
  1456. XAn unescaped `&' in
  1457. X.I replacement
  1458. Xis replaced by the currently matched text.
  1459. XThe character sequence
  1460. X\fI`\\m'\fR,
  1461. Xwhere
  1462. X.I m
  1463. Xis a number in the range [1,9], is replaced by the
  1464. X.IR m th
  1465. Xbackreference expression of the matched text.
  1466. XIf
  1467. X.I replacement
  1468. Xconsists of a single `%', then
  1469. X.I replacement
  1470. Xfrom the last substitution is used.
  1471. XNewlines may be embedded in
  1472. X.I replacement
  1473. Xif they are escaped with a backslash (\\).
  1474. X
  1475. X.TP 8
  1476. X(.,.)s
  1477. XRepeats the last substitution.
  1478. XThis form of the
  1479. X.I `s'
  1480. Xcommand may be suffixed with
  1481. Xany combination of the characters
  1482. X.IR `r' ,
  1483. X.IR `g' ,
  1484. Xand
  1485. X.IR `p' .
  1486. XThe
  1487. X.I `r'
  1488. Xsuffix causes
  1489. Xthe regular expression of the last search to be used instead of the
  1490. Xthat of the last substitution.
  1491. XThe
  1492. X.I `g'
  1493. Xsuffix toggles the global suffix of the last substitution.
  1494. XThe
  1495. X.I `p'
  1496. Xsuffix toggles the print suffix of the last substitution
  1497. XThe current address is set to the last line affected.
  1498. X
  1499. X.TP 8
  1500. X(.,.)t(.)
  1501. XCopies (i.e., transfers) the addressed lines to after the right-hand
  1502. Xdestination address, which may be the address
  1503. X.IR 0
  1504. X(zero).
  1505. XThe current address is set to the last line
  1506. Xcopied.
  1507. X
  1508. X.TP 8
  1509. Xu
  1510. XUndoes the last command and restores the current address
  1511. Xto what it was before the command.
  1512. XThe global commands
  1513. X.IR `g' ,
  1514. X.IR `G' ,
  1515. X.IR `v' ,
  1516. Xand
  1517. X.IR `V' .
  1518. Xare treated as a single command by undo.
  1519. X.I `u'
  1520. Xis its own inverse.
  1521. X
  1522. X.TP 8
  1523. X.RI (1,$)v /pat/command-list
  1524. XApplies
  1525. X.I command-list
  1526. Xto each of the addressed lines not matching a regular expression
  1527. X.IR re .
  1528. XThis is similar to the
  1529. X.I `g'
  1530. Xcommand.
  1531. X
  1532. X.TP 8
  1533. X.RI (1,$)V /re/
  1534. XInteractively edits the addressed lines not matching a regular expression
  1535. X.IR re.
  1536. XThis is similar to the
  1537. X.I `G'
  1538. Xcommand.
  1539. X
  1540. X.TP 8
  1541. X.RI (1,$)w \ file
  1542. XWrites the addressed lines to
  1543. X.IR file .
  1544. XAny previous contents of
  1545. X.I file
  1546. Xis lost without warning.
  1547. XIf there is no default filename, then the default filename is set to
  1548. X.IR file,
  1549. Xotherwise it is unchanged.  If no filename is specified, then the default
  1550. Xfilename is used.
  1551. XThe current address is unchanged.
  1552. X
  1553. X.TP 8
  1554. X.RI (1,$)wq \ file
  1555. XWrites the addressed lines to
  1556. X.IR file ,
  1557. Xand then executes a
  1558. X.I `q'
  1559. Xcommand.
  1560. X
  1561. X.TP 8
  1562. X.RI (1,$)w \ !command
  1563. XWrites the addressed lines to the standard input of
  1564. X.IR `!command' ,
  1565. Xexecuted as described below.
  1566. XThe default filename and current address are unchanged.
  1567. X
  1568. X.TP 8
  1569. X.RI (1,$)W \ file
  1570. XAppends the addressed lines to the end of
  1571. X.IR file .
  1572. XThis is similar to the
  1573. X.I `w'
  1574. Xcommand, expect that the previous contents of file is not clobbered.
  1575. XThe current address is unchanged.
  1576. X
  1577. X.TP 8
  1578. Xx
  1579. XPrompts for an encryption key which is used in subsequent reads and
  1580. Xwrites.  If a newline alone is entered as the key, then encryption is
  1581. Xturned off.  Otherwise, echoing is disabled while a key is read.
  1582. XEncryption/decryption is done using the bdes(1) algorithm.
  1583. X
  1584. X.TP 8
  1585. X.RI (.+1)z n
  1586. XScrolls
  1587. X.I n
  1588. Xlines at a time starting at addressed line.  If
  1589. X.I n
  1590. Xis not specified, then the current window size is used.
  1591. XThe current address is set to the last line printed.
  1592. X
  1593. X.TP 8
  1594. X.RI ! command
  1595. XExecutes
  1596. X.I command
  1597. Xvia
  1598. X.IR sh (1).
  1599. XIf the first character of
  1600. X.I command
  1601. Xis `!', then it is replaced by text of the
  1602. Xprevious
  1603. X.IR `!command' .
  1604. X.B ed
  1605. Xdoes not process
  1606. X.I command
  1607. Xfor backslash (\\) escapes.
  1608. XHowever, an unescaped
  1609. X.I `%'
  1610. Xis replaced by the default file name.
  1611. XWhen the shell returns from execution, a `!'
  1612. Xis printed to the standard output.
  1613. XThe current line is unchanged.
  1614. X
  1615. X.TP 8
  1616. X.RI (.,.)! command
  1617. XReplaces the addressed lines with the output of
  1618. X.I `!command'
  1619. Xas described above.
  1620. XThe current address is set to the last line read.
  1621. X
  1622. X.TP 8
  1623. X($)=
  1624. XPrints the line number of the addressed line.
  1625. X
  1626. X.TP 8
  1627. X(.+1)newline
  1628. XPrints the addressed line, and sets the current address to
  1629. Xthat line.
  1630. X
  1631. X.SH FILES
  1632. X.TP 20
  1633. X/tmp/ed.*
  1634. XBuffer file
  1635. X.PD 0
  1636. X.TP 20
  1637. X\fR./ed.hup\fR, $HOME/ed.hup
  1638. XFirst and second files to which
  1639. X.B ed
  1640. Xattempts to write the  buffer if the terminal hangs up.
  1641. X
  1642. X.SH SEE ALSO
  1643. X
  1644. X.IR vi (1),
  1645. X.IR sed (1),
  1646. X.IR regex (3),
  1647. X.IR bdes (1),
  1648. X.IR sh (1).
  1649. X
  1650. XUSD:12-13
  1651. X
  1652. XB. W. Kernighan and P. J. Plauger,
  1653. X.I Software Tools in Pascal ,
  1654. XAddison-Wesley, 1981.
  1655. X
  1656. X.SH LIMITATIONS
  1657. X.B ed
  1658. Xprocesses
  1659. X.I file
  1660. Xarguments for backslash escapes, i.e.,  in a filename,
  1661. Xany characters preceded by a backslash (\\) are
  1662. Xinterpreted literally.
  1663. X
  1664. XIf a text (non-binary) file is not terminated by a newline character,
  1665. Xthen
  1666. X.B ed
  1667. Xappends one on reading/writing it.  In the case of a binary file,
  1668. X.B ed
  1669. Xdoes not append a newline on reading/writing.
  1670. X
  1671. Xper line overhead: 4 ints
  1672. X
  1673. X.SH DIAGNOSTICS
  1674. XWhen an error occurs,
  1675. X.B ed
  1676. Xprints a `?' and either returns to command mode
  1677. Xor exits if its input is from a script.
  1678. XAn explanation of the last error can be
  1679. Xprinted with the
  1680. X.I `h'
  1681. Xcommand.
  1682. X
  1683. XIf diagnostics are not disabled, attempting to quit
  1684. X.B ed
  1685. Xor edit another file before writing a modified buffer
  1686. Xresults in an error.
  1687. XIf the command is entered a second time, it succeeds,
  1688. Xbut any changes to the buffer are lost.
  1689. END_OF_FILE
  1690.   if test 20771 -ne `wc -c <'ed.1'`; then
  1691.     echo shar: \"'ed.1'\" unpacked with wrong size!
  1692.   fi
  1693.   # end of 'ed.1'
  1694. fi
  1695. if test -f 'ed.h' -a "${1}" != "-c" ; then 
  1696.   echo shar: Will not clobber existing file \"'ed.h'\"
  1697. else
  1698.   echo shar: Extracting \"'ed.h'\" \(7790 characters\)
  1699.   sed "s/^X//" >'ed.h' <<'END_OF_FILE'
  1700. X/* ed.h: type and constant definitions for the ed editor. */
  1701. X/*
  1702. X * Copyright (c) 1993 The Regents of the University of California.
  1703. X * All rights reserved.
  1704. X *
  1705. X * This code is derived from software contributed to Berkeley by
  1706. X * Andrew Moore, Talke Studio.
  1707. X *
  1708. X * Redistribution and use in source and binary forms, with or without
  1709. X * modification, are permitted provided that the following conditions
  1710. X * are met:
  1711. X * 1. Redistributions of source code must retain the above copyright
  1712. X *    notice, this list of conditions and the following disclaimer.
  1713. X * 2. Redistributions in binary form must reproduce the above copyright
  1714. X *    notice, this list of conditions and the following disclaimer in the
  1715. X *    documentation and/or other materials provided with the distribution.
  1716. X * 3. All advertising materials mentioning features or use of this software
  1717. X *    must display the following acknowledgement:
  1718. X *    This product includes software developed by the University of
  1719. X *    California, Berkeley and its contributors.
  1720. X * 4. Neither the name of the University nor the names of its contributors
  1721. X *    may be used to endorse or promote products derived from this software
  1722. X *    without specific prior written permission.
  1723. X *
  1724. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  1725. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  1726. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  1727. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  1728. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  1729. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  1730. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  1731. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  1732. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  1733. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  1734. X * SUCH DAMAGE.
  1735. X *
  1736. X *    @(#)ed.h    5.5 (Berkeley) 3/28/93
  1737. X */
  1738. X
  1739. X#include <unistd.h>
  1740. X#include <errno.h>
  1741. X#if defined(BSD) && BSD >= 199103 || defined(__386BSD__)
  1742. X# include <sys/param.h>        /* for MAXPATHLEN */
  1743. X#endif
  1744. X#include <regex.h>
  1745. X#include <signal.h>
  1746. X
  1747. X#define BITSPERBYTE 8
  1748. X#define BITS(type)  (BITSPERBYTE * (int)sizeof(type))
  1749. X#define CHARBITS    BITS(char)
  1750. X#define INTBITS     BITS(int)
  1751. X#define INTHIBIT    (1 << (INTBITS - 1))
  1752. X
  1753. X#define ERR        (-2)
  1754. X#define EMOD        (-3)
  1755. X#define FATAL        (-4)
  1756. X
  1757. X#ifndef MAXPATHLEN
  1758. X# define MAXPATHLEN 255        /* _POSIX_PATH_MAX */
  1759. X#endif
  1760. X
  1761. X#define MAXFNAME MAXPATHLEN    /* max file name size */
  1762. X#define MINBUFSZ 512        /* minimum buffer size - must be > 0 */
  1763. X#define LINECHARS (INTHIBIT - 1) /* max chars per line */
  1764. X#define SE_MAX 30        /* max subexpressions in a regular expression */
  1765. X
  1766. Xtypedef regex_t pattern_t;
  1767. X
  1768. X#ifdef GNU_REGEX
  1769. X# define FASTMAP_SIZE 256    /* size of fasmap for 8 bit character set */
  1770. X#endif
  1771. X
  1772. X/* Line node */
  1773. Xtypedef struct    line {
  1774. X    struct line    *next;
  1775. X    struct line    *prev;
  1776. X    off_t        seek;        /* address of line in scratch buffer */
  1777. X
  1778. X#define ACTV INTHIBIT            /* active bit: high bit of len */
  1779. X
  1780. X    int        len;        /* length of line */
  1781. X} line_t;
  1782. X
  1783. X
  1784. Xtypedef struct undo {
  1785. X
  1786. X/* type of undo nodes */
  1787. X#define UADD    0
  1788. X#define UDEL     1
  1789. X#define UMOV    2
  1790. X#define VMOV    3
  1791. X
  1792. X    int type;            /* command type */
  1793. X    line_t    *h;            /* head of list */
  1794. X    line_t  *t;            /* tail of list */
  1795. X} undo_t;
  1796. X
  1797. X#ifndef max
  1798. X# define max(a,b) ((a) > (b) ? (a) : (b))
  1799. X#endif
  1800. X#ifndef min
  1801. X# define min(a,b) ((a) < (b) ? (a) : (b))
  1802. X#endif
  1803. X
  1804. X/* nextln: return line after l mod k */
  1805. X#define nextln(l,k)    ((l)+1 > (k) ? 0 : (l)+1)
  1806. X
  1807. X/* nextln: return line before l mod k */
  1808. X#define prevln(l,k)    ((l)-1 < 0 ? (k) : (l)-1)
  1809. X
  1810. X#define    skipblanks() while (isspace(*ibufp) && *ibufp != '\n') ibufp++
  1811. X
  1812. X/* spl1: disable some interrupts (requires reliable signals) */
  1813. X#define spl1() mutex++
  1814. X
  1815. X/* spl0: enable all interrupts; check sigflags (requires reliable signals) */
  1816. X#define spl0() \
  1817. Xif (--mutex == 0) { \
  1818. X    if (sigflags & (1 << SIGHUP)) dohup(SIGHUP); \
  1819. X    if (sigflags & (1 << SIGINT)) dointr(SIGINT); \
  1820. X}
  1821. X
  1822. X#if defined(sun) || defined(NO_REALLOC_NULL)
  1823. X/* CKBUF: assure at least a minimum size for buffer b */
  1824. X#define CKBUF(b,n,i,err) \
  1825. Xif ((i) > (n)) { \
  1826. X    int ti = (n); \
  1827. X    char *ts; \
  1828. X    spl1(); \
  1829. X    if ((b) != NULL) { \
  1830. X        if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
  1831. X            fprintf(stderr, "%s\n", strerror(errno)); \
  1832. X            sprintf(errmsg, "out of memory"); \
  1833. X            spl0(); \
  1834. X            return err; \
  1835. X        } \
  1836. X    } else { \
  1837. X        if ((ts = (char *) malloc(ti += max((i), MINBUFSZ))) == NULL) { \
  1838. X            fprintf(stderr, "%s\n", strerror(errno)); \
  1839. X            sprintf(errmsg, "out of memory"); \
  1840. X            spl0(); \
  1841. X            return err; \
  1842. X        } \
  1843. X    } \
  1844. X    (n) = ti; \
  1845. X    (b) = ts; \
  1846. X    spl0(); \
  1847. X}
  1848. X#else /* NO_REALLOC_NULL */
  1849. X/* CKBUF: assure at least a minimum size for buffer b */
  1850. X#define CKBUF(b,n,i,err) \
  1851. Xif ((i) > (n)) { \
  1852. X    int ti = (n); \
  1853. X    char *ts; \
  1854. X    spl1(); \
  1855. X    if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
  1856. X        fprintf(stderr, "%s\n", strerror(errno)); \
  1857. X        sprintf(errmsg, "out of memory"); \
  1858. X        spl0(); \
  1859. X        return err; \
  1860. X    } \
  1861. X    (n) = ti; \
  1862. X    (b) = ts; \
  1863. X    spl0(); \
  1864. X}
  1865. X#endif /* NO_REALLOC_NULL */
  1866. X
  1867. X/* requeue: link pred before succ */
  1868. X#define requeue(pred, succ) (pred)->next = (succ), (succ)->prev = (pred)
  1869. X
  1870. X/* insqueue: insert elem in circular queue after pred */
  1871. X#define insqueue(elem, pred) \
  1872. X{ \
  1873. X    requeue((elem), (pred)->next); \
  1874. X    requeue((pred), elem); \
  1875. X}
  1876. X
  1877. X/* remqueue: remove elem from circular queue */
  1878. X#define remqueue(elem) requeue((elem)->prev, (elem)->next);
  1879. X
  1880. X/* nultonl: overwrite ASCII NULs with newlines */
  1881. X#define nultonl(s, l) translit(s, l, '\0', '\n')
  1882. X
  1883. X/* nltonul: overwrite newlines with ASCII NULs */
  1884. X#define nltonul(s, l) translit(s, l, '\n', '\0')
  1885. X
  1886. X#ifndef strerror
  1887. X# define strerror(n) sys_errlist[n]
  1888. X#endif
  1889. X
  1890. X#ifndef __P
  1891. X# ifndef __STDC__
  1892. X#  define __P(proto) ()
  1893. X# else
  1894. X#  define __P(proto) proto
  1895. X# endif
  1896. X#endif
  1897. X
  1898. X/* local function declarations */
  1899. Xint append __P((long, int));
  1900. Xint cbcdec __P((char *, FILE *));
  1901. Xint cbcenc __P((char *, int, FILE *));
  1902. Xchar *ckfn __P((char *));
  1903. Xint ckglob __P((void));
  1904. Xint ckrange __P((long, long));
  1905. Xint desflush __P((FILE *));
  1906. Xint desgetc __P((FILE *));
  1907. Xvoid desinit __P((void));
  1908. Xint desputc __P((int, FILE *));
  1909. Xint docmd __P((int));
  1910. Xvoid err __P((char *));
  1911. Xchar *ccl __P((char *));
  1912. Xvoid cvtkey __P((char *, char *));
  1913. Xlong doglob __P((int));
  1914. Xvoid dohup __P((int));
  1915. Xvoid dointr __P((int));
  1916. Xvoid dowinch __P((int));
  1917. Xint doprint __P((long, long, int));
  1918. Xlong doread __P((long, char *));
  1919. Xlong dowrite __P((long, long, char *, char *));
  1920. Xchar *esctos __P((char *));
  1921. Xlong patscan __P((pattern_t *, int));
  1922. Xlong getaddr __P((line_t *));
  1923. Xchar *getcmdv __P((int *, int));
  1924. Xchar *getfn __P((void));
  1925. Xint getkey __P((void));
  1926. Xchar *getlhs __P((int));
  1927. Xint getline __P((void));
  1928. Xint getlist __P((void));
  1929. Xlong getnum __P((int));
  1930. Xlong getone __P((void));
  1931. Xline_t *getlp __P((long));
  1932. Xint getrhs __P((int));
  1933. Xint getshcmd __P((void));
  1934. Xchar *gettxt __P((line_t *));
  1935. Xvoid init_buf __P((void));
  1936. Xint join __P((long, long));
  1937. Xint lndelete __P((long, long));
  1938. Xline_t *lpdup __P((line_t *));
  1939. Xvoid lpqueue __P((line_t *));
  1940. Xvoid makekey __P((char *));
  1941. Xchar *makesub __P((int));
  1942. Xchar *translit __P((char *, int, int, int));
  1943. Xint move __P((long));
  1944. Xint oddesc __P((char *, char *));
  1945. Xvoid onhup __P((int));
  1946. Xvoid onintr __P((int));
  1947. Xpattern_t *optpat __P((void));
  1948. Xvoid putstr __P((char *, int, long, int));
  1949. Xchar *puttxt __P((char *));
  1950. Xvoid quit __P((int));
  1951. Xint regsub __P((pattern_t *, line_t *, int));
  1952. Xint sbclose __P((void));
  1953. Xint sbopen __P((void));
  1954. Xint sgetline __P((FILE *));
  1955. Xint catsub __P((char *, regmatch_t *, int));
  1956. Xint subst __P((pattern_t *, int));
  1957. Xint tobinhex __P((int, int));
  1958. Xint transfer __P((long));
  1959. Xint undo __P((void));
  1960. Xundo_t *upush __P((int, long, long));
  1961. Xvoid ureset __P((void));
  1962. X
  1963. X
  1964. Xextern char *sys_errlist[];
  1965. Xextern int mutex;
  1966. Xextern int sigflags;
  1967. END_OF_FILE
  1968.   if test 7790 -ne `wc -c <'ed.h'`; then
  1969.     echo shar: \"'ed.h'\" unpacked with wrong size!
  1970.   fi
  1971.   # end of 'ed.h'
  1972. fi
  1973. if test -f 're.c' -a "${1}" != "-c" ; then 
  1974.   echo shar: Will not clobber existing file \"'re.c'\"
  1975. else
  1976.   echo shar: Extracting \"'re.c'\" \(4423 characters\)
  1977.   sed "s/^X//" >'re.c' <<'END_OF_FILE'
  1978. X/* re.c: This file contains the regular expression interface routines for
  1979. X   the ed line editor. */
  1980. X/*-
  1981. X * Copyright (c) 1993 The Regents of the University of California.
  1982. X * All rights reserved.
  1983. X *
  1984. X * This code is derived from software contributed to Berkeley
  1985. X * by Andrew Moore, Talke Studio.
  1986. X *
  1987. X * Redistribution and use in source and binary forms, with or without
  1988. X * modification, are permitted provided that the following conditions
  1989. X * are met:
  1990. X * 1. Redistributions of source code must retain the above copyright
  1991. X *    notice, this list of conditions and the following disclaimer.
  1992. X * 2. Redistributions in binary form must reproduce the above copyright
  1993. X *    notice, this list of conditions and the following disclaimer in the
  1994. X *    documentation and/or other materials provided with the distribution.
  1995. X * 3. All advertising materials mentioning features or use of this software
  1996. X *    must display the following acknowledgement:
  1997. X *    This product includes software developed by the University of
  1998. X *    California, Berkeley and its contributors.
  1999. X * 4. Neither the name of the University nor the names of its contributors
  2000. X *    may be used to endorse or promote products derived from this software
  2001. X *    without specific prior written permission.
  2002. X *
  2003. X * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  2004. X * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  2005. X * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  2006. X * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  2007. X * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  2008. X * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  2009. X * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  2010. X * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  2011. X * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  2012. X * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  2013. X * SUCH DAMAGE.
  2014. X */
  2015. X
  2016. X#ifndef lint
  2017. Xstatic char sccsid[] = "@(#)re.c    5.5 (Berkeley) 3/28/93";
  2018. X#endif /* not lint */
  2019. X
  2020. X#include <stdio.h>
  2021. X#include <stdlib.h>
  2022. X#include <string.h>
  2023. X
  2024. X#include "ed.h"
  2025. X
  2026. Xextern char *lhbuf;
  2027. Xextern int lhbufsz;
  2028. Xextern char *ibufp;
  2029. Xextern int ibufsz;
  2030. Xextern int patlock;
  2031. X
  2032. Xchar errmsg[MAXFNAME + 40] = "";
  2033. X
  2034. X/* optpat: return pointer to compiled pattern from command buffer */
  2035. Xpattern_t *
  2036. Xoptpat()
  2037. X{
  2038. X    static pattern_t *exp = NULL;
  2039. X
  2040. X    char *exps;
  2041. X    char delim;
  2042. X    int n;
  2043. X
  2044. X    if ((delim = *ibufp) == '\n') {
  2045. X        if (!exp) sprintf(errmsg, "no previous pattern");
  2046. X        return exp;
  2047. X    } else if (delim == ' ' || *++ibufp == '\n') {
  2048. X        sprintf(errmsg, "invalid pattern delimiter");
  2049. X        return NULL;
  2050. X    } else if (*ibufp == delim) {
  2051. X        sprintf(errmsg, "no previous pattern");
  2052. X        return exp;
  2053. X    } else if ((exps = getlhs(delim)) == NULL)
  2054. X        return NULL;
  2055. X    /* buffer alloc'd && not reserved */
  2056. X    if (exp && !patlock)
  2057. X        regfree(exp);
  2058. X    else if ((exp = (pattern_t *) malloc(sizeof(pattern_t))) == NULL) {
  2059. X        fprintf(stderr, "%s\n", strerror(errno));
  2060. X        sprintf(errmsg, "out of memory");
  2061. X        return NULL;
  2062. X    }
  2063. X    patlock = 0;
  2064. X#ifdef GNU_REGEX
  2065. X    /* initialize pattern buffer */
  2066. X    exp->buffer = NULL;
  2067. X    exp->allocated = 0L;
  2068. X    exp->fastmap = (char *) malloc(FASTMAP_SIZE);
  2069. X    exp->translate = 0;
  2070. X#endif
  2071. X    if (n = regcomp(exp, exps, 0)) {
  2072. X        regerror(n, exp, errmsg, sizeof errmsg);
  2073. X        return NULL;
  2074. X    }
  2075. X    return exp;
  2076. X}
  2077. X
  2078. X
  2079. Xextern int isbinary;
  2080. X
  2081. X/* getlhs: copy a pattern string from the command buffer; return pointer
  2082. X   to the copy */
  2083. Xchar *
  2084. Xgetlhs(delim)
  2085. X    int delim;
  2086. X{
  2087. X    char *nd;
  2088. X    int len;
  2089. X
  2090. X    for (nd = ibufp; *nd != delim && *nd != '\n'; nd++)
  2091. X        switch (*nd) {
  2092. X        default:
  2093. X            break;
  2094. X        case '[':
  2095. X            if ((nd = ccl(++nd)) == NULL) {
  2096. X                sprintf(errmsg, "unbalanced brackets ([])");
  2097. X                return NULL;
  2098. X            }
  2099. X            break;
  2100. X        case '\\':
  2101. X            if (*++nd == '\n') {
  2102. X                sprintf(errmsg, "trailing backslash (\\)");
  2103. X                return NULL;
  2104. X            }
  2105. X            break;
  2106. X        }
  2107. X    len = nd - ibufp;
  2108. X    CKBUF(lhbuf, lhbufsz, len + 1, NULL);
  2109. X    memcpy(lhbuf, ibufp, len);
  2110. X    lhbuf[len] = '\0';
  2111. X    ibufp = nd;
  2112. X    return (isbinary) ? nultonl(lhbuf, len) : lhbuf;
  2113. X}
  2114. X
  2115. X
  2116. X/* ccl: expand a POSIX character class */
  2117. Xchar *
  2118. Xccl(s)
  2119. X    char *s;
  2120. X{
  2121. X    int c, d;
  2122. X
  2123. X    if (*s == '^')
  2124. X        s++;
  2125. X    if (*s == ']')
  2126. X        s++;
  2127. X    for (; *s != ']' && *s != '\n'; s++)
  2128. X        if (*s == '[' && ((d = *(s+1)) == '.' || d == ':' || d == '='))
  2129. X            for (s++, c = *++s; *s != ']' || c != d; s++)
  2130. X                if ((c = *s) == '\n')
  2131. X                    return NULL;
  2132. X    return  (*s == ']') ? s : NULL;
  2133. X}
  2134. END_OF_FILE
  2135.   if test 4423 -ne `wc -c <'re.c'`; then
  2136.     echo shar: \"'re.c'\" unpacked with wrong size!
  2137.   fi
  2138.   # end of 're.c'
  2139. fi
  2140. echo shar: End of archive 2 \(of 3\).
  2141. cp /dev/null ark2isdone
  2142. MISSING=""
  2143. for I in 1 2 3 ; do
  2144.     if test ! -f ark${I}isdone ; then
  2145.     MISSING="${MISSING} ${I}"
  2146.     fi
  2147. done
  2148. if test "${MISSING}" = "" ; then
  2149.     echo You have unpacked all 3 archives.
  2150.     rm -f ark[1-9]isdone
  2151. else
  2152.     echo You still must unpack the following archives:
  2153.     echo "        " ${MISSING}
  2154. fi
  2155. exit 0
  2156. exit 0 # Just in case...
  2157.