#include <sys/queue.h>
#include <err.h>
#include <limits.h>
#include <locale.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <termios.h>
#include <unistd.h>
#include <util.h>
#include "def.h"
#include "kbd.h"
#include "funmap.h"
#include "macro.h"
#ifdef MGLOG
#include "log.h"
#endif
int thisflag;
int lastflag;
int curgoal;
int startrow;
int doaudiblebell;
int dovisiblebell;
int dblspace;
int allbro;
int batch;
struct buffer *curbp;
struct buffer *bheadp;
struct mgwin *curwp;
struct mgwin *wheadp;
struct vhead varhead;
char pat[NPAT];
static void edinit(struct buffer *);
static void pty_init(void);
static __dead void usage(void);
extern char *__progname;
extern void closetags(void);
static __dead void
usage(void)
{
fprintf(stderr, "usage: %s [-nR] [-b file] [-f mode] [-u file] "
"[+number] [file ...]\n",
__progname);
exit(1);
}
int
main(int argc, char **argv)
{
FILE *ffp;
char file[NFILEN];
char *cp, *conffile = NULL, *init_fcn_name = NULL;
char *batchfile = NULL;
PF init_fcn = NULL;
int o, i, nfiles;
int nobackups = 0;
struct buffer *bp = NULL;
if (pledge("stdio rpath wpath cpath fattr chown getpw tty proc exec",
NULL) == -1)
err(1, "pledge");
while ((o = getopt(argc, argv, "nRb:f:u:")) != -1)
switch (o) {
case 'b':
batch = 1;
batchfile = optarg;
break;
case 'R':
allbro = 1;
break;
case 'n':
nobackups = 1;
break;
case 'f':
if (init_fcn_name != NULL)
errx(1, "cannot specify more than one "
"initial function");
init_fcn_name = optarg;
break;
case 'u':
conffile = optarg;
break;
default:
usage();
}
if (batch && (conffile != NULL)) {
fprintf(stderr, "%s: -b and -u are mutually exclusive.\n",
__progname);
exit(1);
}
if (batch) {
pty_init();
conffile = batchfile;
}
if ((ffp = startupfile(NULL, conffile, file, sizeof(file))) == NULL &&
conffile != NULL) {
fprintf(stderr, "%s: Problem with file: %s\n", __progname,
conffile);
exit(1);
}
argc -= optind;
argv += optind;
setlocale(LC_CTYPE, "");
maps_init();
funmap_init();
#ifdef MGLOG
if (!mgloginit())
errx(1, "Unable to create logging environment.");
#endif
{
extern void grep_init(void);
extern void cmode_init(void);
extern void dired_init(void);
dired_init();
grep_init();
cmode_init();
}
if (init_fcn_name &&
(init_fcn = name_function(init_fcn_name)) == NULL)
errx(1, "Unknown function `%s'", init_fcn_name);
vtinit();
dirinit();
edinit(bp);
ttykeymapinit();
bellinit();
dblspace = 1;
update(CMODE);
if (ffp != NULL) {
(void)load(ffp, file);
ffclose(ffp, NULL);
}
if (batch) {
vttidy();
return (0);
}
for (bp = bheadp; bp != NULL; bp = bp->b_bufp) {
bp->b_flag = defb_flag;
for (i = 0; i <= defb_nmodes; i++) {
bp->b_modes[i] = defb_modes[i];
}
}
if (init_fcn)
init_fcn(FFOTHARG, 1);
if (nobackups)
makebkfile(FFARG, 0);
for (nfiles = 0, i = 0; i < argc; i++) {
if (argv[i][0] == '+' && strlen(argv[i]) >= 2) {
long long lval;
const char *errstr;
lval = strtonum(&argv[i][1], INT_MIN, INT_MAX, &errstr);
if (argv[i][1] == '\0' || errstr != NULL)
goto notnum;
startrow = lval;
} else {
notnum:
cp = adjustname(argv[i], FALSE);
if (cp != NULL) {
if (nfiles == 1)
splitwind(0, 1);
if (fisdir(cp) == TRUE) {
(void)do_dired(cp);
continue;
}
if ((curbp = findbuffer(cp)) == NULL) {
vttidy();
errx(1, "Can't find current buffer!");
}
(void)showbuffer(curbp, curwp, 0);
if (readin(cp) != TRUE)
killbuffer(curbp);
else {
if (init_fcn_name)
init_fcn(FFOTHARG, 1);
nfiles++;
}
if (allbro)
curbp->b_flag |= BFREADONLY;
}
}
}
if (nfiles > 2)
listbuffers(0, 1);
thisflag = 0;
for (;;) {
if (epresf == KCLEAR)
eerase();
if (epresf == TRUE)
epresf = KCLEAR;
if (winch_flag) {
do_redraw(0, 0, TRUE);
winch_flag = 0;
}
update(CMODE);
lastflag = thisflag;
thisflag = 0;
switch (doin()) {
case TRUE:
break;
case ABORT:
ewprintf("Quit");
case FALSE:
default:
macrodef = FALSE;
}
}
}
static void
edinit(struct buffer *bp)
{
struct mgwin *wp;
bheadp = NULL;
bp = bfind("*scratch*", TRUE);
if (bp == NULL)
panic("edinit");
wp = new_window(bp);
if (wp == NULL)
panic("edinit: Out of memory");
curbp = bp;
wheadp = wp;
curwp = wp;
wp->w_wndp = NULL;
wp->w_linep = wp->w_dotp = bp->b_headp;
wp->w_ntrows = nrow - 2;
wp->w_rflag = WFMODE | WFFULL;
}
static void
pty_init(void)
{
struct winsize ws;
int master;
int slave;
memset(&ws, 0, sizeof(ws));
ws.ws_col = 80,
ws.ws_row = 24;
openpty(&master, &slave, NULL, NULL, &ws);
login_tty(slave);
return;
}
int
quit(int f, int n)
{
int s;
if ((s = anycb(FALSE)) == ABORT)
return (ABORT);
if (s == FIOERR || s == UERROR)
return (FALSE);
if (s == FALSE
|| eyesno("Modified buffers exist; really exit") == TRUE) {
vttidy();
closetags();
exit(0);
}
return (TRUE);
}
int
ctrlg(int f, int n)
{
return (ABORT);
}