#include <sys/types.h>
#if defined(BSD) && BSD >= 199103 || defined(__386BSD__)
# include <sys/param.h>
#endif
#include <errno.h>
#if defined(sun) || defined(__NetBSD__) || defined(__APPLE__)
# include <limits.h>
#endif
#include <regex.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#define ERR (-2)
#define EMOD (-3)
#define FATAL (-4)
#ifndef MAXPATHLEN
# define MAXPATHLEN 255
#endif
#define MINBUFSZ 512
#define SE_MAX 30
#ifdef INT_MAX
# define LINECHARS INT_MAX
#else
# define LINECHARS MAXINT
#endif
#define GLB 001
#define GPR 002
#define GLS 004
#define GNP 010
#define GSG 020
typedef regex_t pattern_t;
typedef struct line {
struct line *q_forw;
struct line *q_back;
off_t seek;
int len;
} line_t;
typedef struct undo {
#define UADD 0
#define UDEL 1
#define UMOV 2
#define VMOV 3
int type;
line_t *h;
line_t *t;
} undo_t;
#ifndef max
# define max(a,b) ((a) > (b) ? (a) : (b))
#endif
#ifndef min
# define min(a,b) ((a) < (b) ? (a) : (b))
#endif
#define INC_MOD(l, k) ((l) + 1 > (k) ? 0 : (l) + 1)
#define DEC_MOD(l, k) ((l) - 1 < 0 ? (k) : (l) - 1)
#define SPL1() mutex++
#define SPL0() \
if (--mutex == 0) { \
if (sigflags & (1 << (SIGHUP - 1))) handle_hup(SIGHUP); \
if (sigflags & (1 << (SIGINT - 1))) handle_int(SIGINT); \
}
#define STRTOL(i, p) { \
if (((i = strtol(p, &p, 10)) == LONG_MIN || i == LONG_MAX) && \
errno == ERANGE) { \
sprintf(errmsg, "number out of range"); \
i = 0; \
return ERR; \
} \
}
#if defined(sun) || defined(NO_REALLOC_NULL)
#define REALLOC(b,n,i,err) \
if ((i) > (n)) { \
int ti = (n); \
char *ts; \
SPL1(); \
if ((b) != NULL) { \
if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
} else { \
if ((ts = (char *) malloc(ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
} \
(n) = ti; \
(b) = ts; \
SPL0(); \
}
#else
#define REALLOC(b,n,i,err) \
if ((i) > (n)) { \
int ti = (n); \
char *ts; \
SPL1(); \
if ((ts = (char *) realloc((b), ti += max((i), MINBUFSZ))) == NULL) { \
fprintf(stderr, "%s\n", strerror(errno)); \
sprintf(errmsg, "out of memory"); \
SPL0(); \
return err; \
} \
(n) = ti; \
(b) = ts; \
SPL0(); \
}
#endif
#define REQUE(pred, succ) (pred)->q_forw = (succ), (succ)->q_back = (pred)
#define INSQUE(elem, pred) \
{ \
REQUE((elem), (pred)->q_forw); \
REQUE((pred), elem); \
}
#define REMQUE(elem) REQUE((elem)->q_back, (elem)->q_forw);
#define NUL_TO_NEWLINE(s, l) translit_text(s, l, '\0', '\n')
#define NEWLINE_TO_NUL(s, l) translit_text(s, l, '\n', '\0')
#ifdef sun
# define strerror(n) sys_errlist[n]
#endif
#ifndef __P
# ifndef __STDC__
# define __P(proto) ()
# else
# define __P(proto) proto
# endif
#endif
void add_line_node __P((line_t *));
int append_lines __P((long));
int apply_subst_template __P((char *, regmatch_t *, int, int));
int build_active_list __P((int));
int cbc_decode __P((char *, FILE *));
int cbc_encode __P((char *, int, FILE *));
int check_addr_range __P((long, long));
void clear_active_list __P((void));
void clear_undo_stack __P((void));
int close_sbuf __P((void));
int copy_lines __P((long));
int delete_lines __P((long, long));
void des_error __P((char *));
int display_lines __P((long, long, int));
line_t *dup_line_node __P((line_t *));
int exec_command __P((void));
long exec_global __P((int, int));
void expand_des_key __P((char *, char *));
int extract_addr_range __P((void));
char *extract_pattern __P((int));
int extract_subst_tail __P((int *, long *));
char *extract_subst_template __P((void));
int filter_lines __P((long, long, char *));
int flush_des_file __P((FILE *));
line_t *get_addressed_line_node __P((long));
pattern_t *get_compiled_pattern __P((void));
int get_des_char __P((FILE *));
char *get_extended_line __P((int *, int));
char *get_filename __P((void));
int get_keyword __P((void));
long get_line_node_addr __P((line_t *));
long get_matching_node_addr __P((pattern_t *, int));
long get_marked_node_addr __P((int));
char *get_sbuf_line __P((line_t *));
int get_shell_command __P((void));
int get_stream_line __P((FILE *));
int get_tty_line __P((void));
void handle_hup __P((int));
void handle_int __P((int));
void handle_winch __P((int));
int has_trailing_escape __P((char *, char *));
int hex_to_binary __P((int, int));
void init_buffers __P((void));
void init_des_cipher __P((void));
int is_legal_filename __P((char *));
int join_lines __P((long, long));
int mark_line_node __P((line_t *, int));
int move_lines __P((long));
line_t *next_active_node __P((void));
long next_addr __P((void));
int open_sbuf __P((void));
char *parse_char_class __P((char *));
int pop_undo_stack __P((void));
undo_t *push_undo_stack __P((int, long, long));
int put_des_char __P((int, FILE *));
char *put_sbuf_line __P((char *));
int put_stream_line __P((FILE *, char *, int));
int put_tty_line __P((char *, int, long, int));
void quit __P((int));
long read_file __P((char *, long));
long read_stream __P((FILE *, long));
void replace_marks __P((line_t *, line_t *));
int search_and_replace __P((pattern_t *, int, int));
int set_active_node __P((line_t *));
void set_des_key __P((char *));
void signal_hup __P((int));
void signal_int __P((int));
char *strip_escapes __P((char *));
int substitute_matching_text __P((pattern_t *, line_t *, int, int));
char *translit_text __P((char *, int, int, int));
void unmark_line_node __P((line_t *));
void unset_active_nodes __P((line_t *, line_t *));
long write_file __P((char *, char *, long, long));
long write_stream __P((FILE *, long, long));
extern char stdinbuf[];
extern char *ibuf;
extern char *ibufp;
extern int ibufsz;
extern int isbinary;
extern int isglobal;
extern int modified;
extern int mutex;
extern int sigflags;
extern long addr_last;
extern long current_addr;
extern char errmsg[];
extern long first_addr;
extern int lineno;
extern long second_addr;
extern int posixly_correct;
#ifdef sun
extern char *sys_errlist[];
#endif