#include "ex.h"
#include "ex_argv.h"
#include "ex_temp.h"
#include "ex_tty.h"
#include <stdlib.h>
#include <locale.h>
#include <stdio.h>
#ifdef TRACE
unsigned char tttrace[BUFSIZ];
#endif
#define EQ(a, b) (strcmp(a, b) == 0)
char *strrchr();
void init_re(void);
unsigned char *Version = (unsigned char *)"Version SVR4.0, Solaris 2.5.0";
#ifdef XPG4
unsigned char *savepat = (unsigned char *) NULL;
#endif
static unsigned char cryptkey[19];
static void usage(unsigned char *);
static int validate_exrc(unsigned char *);
void init(void);
int
main(int ac, char *av[])
{
extern char *optarg;
extern int optind;
unsigned char *rcvname = 0;
unsigned char *cp;
int c;
unsigned char *cmdnam;
bool recov = 0;
bool ivis = 0;
bool itag = 0;
bool fast = 0;
extern int verbose;
int argcounter = 0;
extern int tags_flag;
unsigned char scratch [PATH_MAX+1];
int vret = 0;
unsigned char exrcpath [PATH_MAX+1];
int toptseen = 0;
#ifdef TRACE
unsigned char *tracef;
#endif
tagflg = 0;
(void) setlocale(LC_ALL, "");
#if !defined(TEXT_DOMAIN)
#define TEXT_DOMAIN "SYS_TEST"
#endif
(void) textdomain(TEXT_DOMAIN);
(void) gTTY(2);
normf = tty;
ppid = getpid();
lines = 24;
columns = 80;
if ((cmdnam = (unsigned char *)strrchr(av[0], '/')) != 0)
cmdnam++;
else
cmdnam = (unsigned char *)av[0];
if (EQ((char *)cmdnam, "vi"))
ivis = 1;
else if (EQ(cmdnam, "view")) {
ivis = 1;
value(vi_READONLY) = 1;
} else if (EQ(cmdnam, "vedit")) {
ivis = 1;
value(vi_NOVICE) = 1;
value(vi_REPORT) = 1;
value(vi_MAGIC) = 0;
value(vi_SHOWMODE) = 1;
} else if (EQ(cmdnam, "edit")) {
value(vi_NOVICE) = 1;
value(vi_REPORT) = 1;
value(vi_MAGIC) = 0;
value(vi_SHOWMODE) = 1;
}
#ifdef XPG4
{
struct winsize jwin;
char *envptr;
envlines = envcolumns = -1;
oldlines = oldcolumns = -1;
if (ioctl(0, TIOCGWINSZ, &jwin) != -1) {
oldlines = jwin.ws_row;
oldcolumns = jwin.ws_col;
}
if ((envptr = getenv("LINES")) != NULL &&
*envptr != '\0' && isdigit(*envptr)) {
if ((envlines = atoi(envptr)) <= 0) {
envlines = -1;
}
}
if ((envptr = getenv("COLUMNS")) != NULL &&
*envptr != '\0' && isdigit(*envptr)) {
if ((envcolumns = atoi(envptr)) <= 0) {
envcolumns = -1;
}
}
}
#endif
draino();
pstop();
oldhup = signal(SIGHUP, SIG_IGN);
if (oldhup == SIG_DFL)
signal(SIGHUP, onhup);
oldquit = signal(SIGQUIT, SIG_IGN);
ruptible = signal(SIGINT, SIG_IGN) == SIG_DFL;
if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
signal(SIGTERM, onhup);
signal(SIGILL, oncore);
signal(SIGTRAP, oncore);
signal(SIGIOT, oncore);
signal(SIGFPE, oncore);
signal(SIGBUS, oncore);
signal(SIGSEGV, oncore);
signal(SIGPIPE, oncore);
init_re();
while (1) {
#ifdef TRACE
while ((c = getopt(ac, (char **)av, "VU:Lc:Tvt:rlw:xRCsS")) !=
EOF)
#else
while ((c = getopt(ac, (char **)av,
"VLc:vt:rlw:xRCsS")) != EOF)
#endif
switch (c) {
case 's':
hush = 1;
value(vi_AUTOPRINT) = 0;
fast++;
break;
case 'R':
value(vi_READONLY) = 1;
break;
case 'S':
tags_flag = 1;
break;
#ifdef TRACE
case 'T':
tracef = (unsigned char *)"trace";
goto trace;
case 'U':
tracef = tttrace;
strcpy(tracef, optarg);
trace:
trace = fopen((char *)tracef, "w");
#define tracbuf NULL
if (trace == NULL)
viprintf("Trace create error\n");
else
setbuf(trace, (char *)tracbuf);
break;
#endif
case 'c':
if (optarg != NULL)
firstpat = (unsigned char *)optarg;
else
firstpat = (unsigned char *)"";
break;
case 'l':
value(vi_LISP) = 1;
value(vi_SHOWMATCH) = 1;
break;
case 'r':
if (av[optind] && (c = av[optind][0]) &&
c != '-') {
if ((strlen(av[optind])) >=
sizeof (savedfile)) {
(void) fprintf(stderr, gettext(
"Recovered file name"
" too long\n"));
exit(1);
}
rcvname = (unsigned char *)av[optind];
optind++;
}
case 'L':
recov++;
break;
case 'V':
verbose = 1;
break;
case 't':
if (toptseen) {
usage(cmdnam);
exit(1);
} else {
toptseen++;
}
itag = tagflg = 1;
if (strlcpy(lasttag, optarg,
sizeof (lasttag)) >= sizeof (lasttag)) {
(void) fprintf(stderr, gettext("Tag"
" file name too long\n"));
exit(1);
}
break;
case 'w':
defwind = 0;
if (optarg[0] == NULL)
defwind = 3;
else for (cp = (unsigned char *)optarg;
isdigit(*cp); cp++)
defwind = 10*defwind + *cp - '0';
if (defwind < 0)
defwind = 3;
break;
case 'C':
crflag = 1;
xflag = 1;
break;
case 'x':
xflag = 1;
crflag = -1;
break;
case 'v':
ivis = 1;
break;
default:
usage(cmdnam);
exit(1);
}
if (av[optind] && av[optind][0] == '+' &&
av[optind-1] && strcmp(av[optind-1], "--")) {
firstpat = (unsigned char *)&av[optind][1];
optind++;
continue;
} else if (av[optind] && av[optind][0] == '-' &&
av[optind-1] && strcmp(av[optind-1], "--")) {
hush = 1;
value(vi_AUTOPRINT) = 0;
fast++;
optind++;
continue;
}
break;
}
if (isatty(0) == 0) {
if (verbose == 1) {
ivis = 0;
}
if (ivis == 0) {
hush = 1;
value(vi_AUTOPRINT) = 0;
fast++;
}
}
ac -= optind;
av = &av[optind];
for (argcounter = 0; argcounter < ac; argcounter++) {
if ((strlen(av[argcounter])) >= sizeof (savedfile)) {
(void) fprintf(stderr, gettext("File argument"
" too long\n"));
exit(1);
}
}
#ifdef SIGTSTP
if (!hush && signal(SIGTSTP, SIG_IGN) == SIG_DFL)
signal(SIGTSTP, onsusp), dosusp++;
#endif
if (xflag) {
permflag = 1;
if ((kflag = run_setkey(perm,
(key = (unsigned char *)getpass(
gettext("Enter key:"))))) == -1) {
kflag = 0;
xflag = 0;
smerror(gettext("Encryption facility not available\n"));
}
if (kflag == 0)
crflag = 0;
else {
strcpy(cryptkey, "CrYpTkEy=XXXXXXXXX");
strcpy(cryptkey + 9, key);
if (putenv((char *)cryptkey) != 0)
smerror(gettext(" Cannot copy key to environment"));
}
}
#ifndef PRESUNEUC
localize();
#endif
fendcore = (line *) sbrk(0);
endcore = fendcore - 2;
if (recov) {
if (ac == 0 && (rcvname == NULL || *rcvname == NULL)) {
ppid = 0;
setrupt();
execlp(EXRECOVER, "exrecover", "-r", (char *)0);
filioerr(EXRECOVER);
exit(++errcnt);
}
if (rcvname && *rcvname)
(void) strlcpy(savedfile, rcvname, sizeof (savedfile));
else {
(void) strlcpy(savedfile, *av++, sizeof (savedfile));
ac--;
}
}
argv0 = (unsigned char **)av;
argc0 = ac;
args0 = (unsigned char *)av[0];
erewind();
if (setexit() == 0) {
setrupt();
intty = isatty(0);
value(vi_PROMPT) = intty;
if (((cp = (unsigned char *)getenv("SHELL")) != NULL) &&
(*cp != '\0')) {
if (strlen(cp) < sizeof (shell)) {
(void) strlcpy(shell, cp, sizeof (shell));
}
}
if (fast)
setterm((unsigned char *)"dumb");
else {
gettmode();
cp = (unsigned char *)getenv("TERM");
if (cp == NULL || *cp == '\0')
cp = (unsigned char *)"unknown";
setterm(cp);
}
}
dot = zero = truedol = unddol = dol = fendcore;
one = zero+1;
{
int i;
for (i = 0; i <= 'z'-'a'+1; i++)
names[i] = 1;
}
if (setexit() == 0 && !fast) {
if ((globp =
(unsigned char *) getenv("EXINIT")) && *globp) {
if (ivis)
inexrc = 1;
commands(1, 1);
inexrc = 0;
} else {
globp = 0;
if ((cp = (unsigned char *) getenv("HOME")) !=
0 && *cp) {
strncpy(scratch, cp, sizeof (scratch) - 1);
strncat(scratch, "/.exrc",
sizeof (scratch) - 1 - strlen(scratch));
if (ivis)
inexrc = 1;
if ((vret = validate_exrc(scratch)) == 0) {
source(scratch, 1);
} else {
if (vret == -1) {
error(gettext(
"Not owner of .exrc "
"or .exrc is group or "
"world writable"));
}
}
inexrc = 0;
}
}
if (value(vi_EXRC)) {
if (ivis)
inexrc = 1;
if ((cp = (unsigned char *) getenv("PWD")) != 0 &&
*cp) {
strncpy(exrcpath, cp, sizeof (exrcpath) - 1);
strncat(exrcpath, "/.exrc",
sizeof (exrcpath) - 1 - strlen(exrcpath));
if (strcmp(scratch, exrcpath) != 0) {
if ((vret =
validate_exrc(exrcpath)) == 0) {
source(exrcpath, 1);
} else {
if (vret == -1) {
error(gettext(
"Not owner of "
".exrc or .exrc "
"is group or world "
"writable"));
}
}
}
}
inexrc = 0;
}
}
init();
if (setexit() == 0) {
if (recov)
globp = (unsigned char *)"recover";
else if (itag) {
globp = ivis ? (unsigned char *)"tag" :
(unsigned char *)"tag|p";
#ifdef XPG4
if (firstpat != NULL) {
savepat = firstpat;
firstpat = NULL;
inglobal = 1;
commands(1, 1);
globp = savepat;
commands(1, 1);
inglobal = 0;
globp = savepat = NULL;
if (!ivis) {
setdot();
nonzero();
plines(addr1, addr2, 1);
}
}
#endif
} else if (argc)
globp = (unsigned char *)"next";
if (ivis)
initev = globp;
else if (globp) {
inglobal = 1;
commands(1, 1);
inglobal = 0;
}
}
if (ivis) {
#ifdef XPG4
if (!itag && (dol > zero))
#else
if (dol > zero)
#endif
dot = one;
globp = (unsigned char *)"visual";
if (setexit() == 0)
commands(1, 1);
}
seenprompt = 1;
ungetchar(0);
globp = 0;
initev = 0;
setlastchar('\n');
setexit();
commands(0, 0);
cleanup(1);
return (errcnt);
}
void
init(void)
{
int i;
void (*pstat)();
fileinit();
dot = zero = truedol = unddol = dol = fendcore;
one = zero+1;
undkind = UNDNONE;
chng = 0;
edited = 0;
for (i = 0; i <= 'z'-'a'+1; i++)
names[i] = 1;
anymarks = 0;
if (xflag) {
xtflag = 1;
pstat = signal(SIGINT, SIG_IGN);
if (tpermflag)
(void) crypt_close(tperm);
tpermflag = 1;
if (makekey(tperm) != 0) {
xtflag = 0;
smerror(gettext(
"Warning--Cannot encrypt temporary buffer\n"));
}
signal(SIGINT, pstat);
}
}
unsigned char *
tailpath(p)
unsigned char *p;
{
unsigned char *r;
for (r = p; *p; p++)
if (*p == '/')
r = p+1;
return (r);
}
static int
validate_exrc(unsigned char *exrc_path)
{
struct stat64 exrc_stat;
int process_uid;
if (stat64((char *)exrc_path, &exrc_stat) == -1)
return (0);
process_uid = geteuid();
if (process_uid && process_uid != exrc_stat.st_uid)
return (-1);
if ((exrc_stat.st_mode & (S_IWGRP | S_IWOTH)) != 0)
return (-1);
return (0);
}
static void
usage(unsigned char *name)
{
char buf[160];
#ifdef TRACE
(void) snprintf(buf, sizeof (buf), gettext(
"Usage: %s [- | -s] [-l] [-L] [-wn] "
"[-R] [-S] [-r [file]] [-t tag] [-T] [-U tracefile]\n"
"[-v] [-V] [-x] [-C] [+cmd | -c cmd] file...\n"), name);
#else
(void) snprintf(buf, sizeof (buf), gettext(
"Usage: %s [- | -s] [-l] [-L] [-wn] "
"[-R] [-S] [-r [file]] [-t tag]\n"
"[-v] [-V] [-x] [-C] [+cmd | -c cmd] file...\n"), name);
#endif
(void) write(2, buf, strlen(buf));
}