/* ARGSUSED */ int showcwdir(int f, int n) { ewprintf("Current directory: %s", mgcwd); return (TRUE); }
/* * Read the file "fname" into the current buffer. Make all of the text * in the buffer go away, after checking for unsaved changes. This is * called by the "read" command, the "visit" command, and the mainline * (for "mg file"). */ int readin(char *fname) { struct mgwin *wp; struct stat statbuf; int status, i, ro = FALSE; PF *ael; char dp[NFILEN]; /* might be old */ if (bclear(curbp) != TRUE) return (TRUE); /* Clear readonly. May be set by autoexec path */ curbp->b_flag &= ~BFREADONLY; if ((status = insertfile(fname, fname, TRUE)) != TRUE) { dobeep(); ewprintf("File is not readable: %s", fname); return (FALSE); } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_dotp = wp->w_linep = bfirstlp(curbp); wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; } } /* * Call auto-executing function if we need to. */ if ((ael = find_autoexec(fname)) != NULL) { for (i = 0; ael[i] != NULL; i++) (*ael[i])(0, 1); free(ael); } /* no change */ curbp->b_flag &= ~BFCHG; /* * Set the buffer READONLY flag if any of following are true: * 1. file is a directory. * 2. file is read-only. * 3. file doesn't exist and directory is read-only. */ if (fisdir(fname) == TRUE) { ro = TRUE; } else if ((access(fname, W_OK) == -1)) { if (errno != ENOENT) { ro = TRUE; } else if (errno == ENOENT) { (void)xdirname(dp, fname, sizeof(dp)); (void)strlcat(dp, "/", sizeof(dp)); /* Missing directory; keep buffer rw, like emacs */ if (stat(dp, &statbuf) == -1 && errno == ENOENT) { if (eyorn("Missing directory, create") == TRUE) (void)do_makedir(dp); } else if (access(dp, W_OK) == -1 && errno == EACCES) { ewprintf("File not found and directory" " write-protected"); ro = TRUE; } } } if (ro == TRUE) curbp->b_flag |= BFREADONLY; if (startrow) { gotoline(FFARG, startrow); startrow = 0; } undo_add_modified(); return (status); }
int insertfile(char *fname, char *newname, int replacebuf) { struct buffer *bp; struct line *lp1, *lp2; struct line *olp; /* line we started at */ struct mgwin *wp; int nbytes, s, nline = 0, siz, x, x2; int opos; /* offset we started at */ int oline; /* original line number */ FILE *ffp; if (replacebuf == TRUE) x = undo_enable(FFRAND, 0); else x = undo_enabled(); lp1 = NULL; if (line == NULL) { line = malloc(NLINE); if (line == NULL) panic("out of memory"); linesize = NLINE; } /* cheap */ bp = curbp; if (newname != NULL) { (void)strlcpy(bp->b_fname, newname, sizeof(bp->b_fname)); (void)xdirname(bp->b_cwd, newname, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); } /* hard file open */ if ((s = ffropen(&ffp, fname, (replacebuf == TRUE) ? bp : NULL)) == FIOERR) goto out; if (s == FIOFNF) { /* file not found */ if (newname != NULL) ewprintf("(New file)"); else ewprintf("(File not found)"); goto out; } else if (s == FIODIR) { /* file was a directory */ if (replacebuf == FALSE) { dobeep(); ewprintf("Cannot insert: file is a directory, %s", fname); goto cleanup; } killbuffer(bp); bp = dired_(fname); undo_enable(FFRAND, x); if (bp == NULL) return (FALSE); curbp = bp; return (showbuffer(bp, curwp, WFFULL | WFMODE)); } else { (void)xdirname(bp->b_cwd, fname, sizeof(bp->b_cwd)); (void)strlcat(bp->b_cwd, "/", sizeof(bp->b_cwd)); } opos = curwp->w_doto; oline = curwp->w_dotline; /* * Open a new line at dot and start inserting after it. * We will delete this newline after insertion. * Disable undo, as we create the undo record manually. */ x2 = undo_enable(FFRAND, 0); (void)lnewline(); olp = lback(curwp->w_dotp); undo_enable(FFRAND, x2); nline = 0; siz = 0; while ((s = ffgetline(ffp, line, linesize, &nbytes)) != FIOERR) { retry: siz += nbytes + 1; switch (s) { case FIOSUC: /* FALLTHRU */ case FIOEOF: ++nline; if ((lp1 = lalloc(nbytes)) == NULL) { /* keep message on the display */ s = FIOERR; undo_add_insert(olp, opos, siz - nbytes - 1 - 1); goto endoffile; } bcopy(line, <ext(lp1)[0], nbytes); lp2 = lback(curwp->w_dotp); lp2->l_fp = lp1; lp1->l_fp = curwp->w_dotp; lp1->l_bp = lp2; curwp->w_dotp->l_bp = lp1; if (s == FIOEOF) { undo_add_insert(olp, opos, siz - 1); goto endoffile; } break; case FIOLONG: { /* a line too long to fit in our buffer */ char *cp; int newsize; newsize = linesize * 2; if (newsize < 0 || (cp = malloc(newsize)) == NULL) { dobeep(); ewprintf("Could not allocate %d bytes", newsize); s = FIOERR; goto endoffile; } bcopy(line, cp, linesize); free(line); line = cp; s = ffgetline(ffp, line + linesize, linesize, &nbytes); nbytes += linesize; linesize = newsize; if (s == FIOERR) goto endoffile; goto retry; } default: dobeep(); ewprintf("Unknown code %d reading file", s); s = FIOERR; break; } } endoffile: /* ignore errors */ (void)ffclose(ffp, NULL); /* don't zap an error */ if (s == FIOEOF) { if (nline == 1) ewprintf("(Read 1 line)"); else ewprintf("(Read %d lines)", nline); } /* set mark at the end of the text */ curwp->w_dotp = curwp->w_markp = lback(curwp->w_dotp); curwp->w_marko = llength(curwp->w_markp); curwp->w_markline = oline + nline + 1; /* * if we are at the end of the file, ldelnewline is a no-op, * but we still need to decrement the line and markline counts * as we've accounted for this fencepost in our arithmetic */ if (lforw(curwp->w_dotp) == curwp->w_bufp->b_headp) { curwp->w_bufp->b_lines--; curwp->w_markline--; } else (void)ldelnewline(); curwp->w_dotp = olp; curwp->w_doto = opos; curwp->w_dotline = oline; if (olp == curbp->b_headp) curwp->w_dotp = lforw(olp); if (newname != NULL) bp->b_flag |= BFCHG | BFBAK; /* Need a backup. */ else bp->b_flag |= BFCHG; /* * If the insert was at the end of buffer, set lp1 to the end of * buffer line, and lp2 to the beginning of the newly inserted text. * (Otherwise lp2 is set to NULL.) This is used below to set * pointers in other windows correctly if they are also at the end of * buffer. */ lp1 = bp->b_headp; if (curwp->w_markp == lp1) { lp2 = curwp->w_dotp; } else { /* delete extraneous newline */ (void)ldelnewline(); out: lp2 = NULL; } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_rflag |= WFMODE | WFEDIT; if (wp != curwp && lp2 != NULL) { if (wp->w_dotp == lp1) wp->w_dotp = lp2; if (wp->w_markp == lp1) wp->w_markp = lp2; if (wp->w_linep == lp1) wp->w_linep = lp2; } } } bp->b_lines += nline; cleanup: undo_enable(FFRAND, x); /* return FALSE if error */ return (s != FIOERR); }
struct buffer * compile_mode(const char *name, const char *command) { struct buffer *bp; FILE *fpipe; char *buf; size_t len; int ret, n; char cwd[NFILEN], qcmd[NFILEN]; char timestr[NTIME]; time_t t; n = snprintf(qcmd, sizeof(qcmd), "%s 2>&1", command); if (n < 0 || n >= sizeof(qcmd)) return (NULL); bp = bfind(name, TRUE); if (bclear(bp) != TRUE) return (NULL); if (getbufcwd(bp->b_cwd, sizeof(bp->b_cwd)) != TRUE) return (NULL); addlinef(bp, "cd %s", bp->b_cwd); addline(bp, qcmd); addline(bp, ""); if (getcwd(cwd, sizeof(cwd)) == NULL) panic("Can't get current directory!"); if (chdir(bp->b_cwd) == -1) { ewprintf("Can't change dir to %s", bp->b_cwd); return (NULL); } if ((fpipe = popen(qcmd, "r")) == NULL) { ewprintf("Problem opening pipe"); return (NULL); } /* * We know that our commands are nice and the last line will end with * a \n, so we don't need to try to deal with the last line problem * in fgetln. */ while ((buf = fgetln(fpipe, &len)) != NULL) { buf[len - 1] = '\0'; addline(bp, buf); } ret = pclose(fpipe); t = time(NULL); strftime(timestr, sizeof(timestr), "%a %b %e %T %Y", localtime(&t)); addline(bp, ""); if (ret != 0) addlinef(bp, "Command exited abnormally with code %d" " at %s", ret, timestr); else addlinef(bp, "Command finished at %s", timestr); bp->b_dotp = bfirstlp(bp); bp->b_modes[0] = name_mode("fundamental"); bp->b_modes[1] = name_mode("compile"); bp->b_nmodes = 1; compile_buffer = bp; if (chdir(cwd) == -1) { ewprintf("Can't change dir back to %s", cwd); return (NULL); } return (bp); }
/* ARGSUSED */ static int compile_goto_error(int f, int n) { struct buffer *bp; struct mgwin *wp; char *fname, *line, *lp, *ln; int lineno; char *adjf, path[NFILEN]; const char *errstr; struct line *last; compile_win = curwp; compile_buffer = curbp; last = blastlp(compile_buffer); retry: /* last line is compilation result */ if (curwp->w_dotp == last) return (FALSE); if ((line = linetostr(curwp->w_dotp)) == NULL) return (FALSE); lp = line; if ((fname = strsep(&lp, ":")) == NULL || *fname == '\0') goto fail; if ((ln = strsep(&lp, ":")) == NULL || *ln == '\0') goto fail; lineno = (int)strtonum(ln, INT_MIN, INT_MAX, &errstr); if (errstr) goto fail; if (fname && fname[0] != '/') { if (getbufcwd(path, sizeof(path)) == FALSE) goto fail; if (strlcat(path, fname, sizeof(path)) >= sizeof(path)) goto fail; adjf = path; } else { adjf = adjustname(fname, TRUE); } free(line); if (adjf == NULL) return (FALSE); if ((bp = findbuffer(adjf)) == NULL) return (FALSE); if ((wp = popbuf(bp, WNONE)) == NULL) return (FALSE); curbp = bp; curwp = wp; if (bp->b_fname[0] == '\0') readin(adjf); gotoline(FFARG, lineno); return (TRUE); fail: free(line); if (curwp->w_dotp != blastlp(curbp)) { curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_rflag |= WFMOVE; goto retry; } ewprintf("No more hits"); return (FALSE); }
/* ARGSUSED */ int splitwind(int f, int n) { struct mgwin *wp, *wp1, *wp2; struct line *lp; int ntru, ntrd, ntrl; if (curwp->w_ntrows < 3) { ewprintf("Cannot split a %d line window", curwp->w_ntrows); return (FALSE); } wp = new_window(curbp); if (wp == NULL) { ewprintf("Unable to create a window"); return (FALSE); } /* use the current dot and mark */ wp->w_dotp = curwp->w_dotp; wp->w_doto = curwp->w_doto; wp->w_markp = curwp->w_markp; wp->w_marko = curwp->w_marko; wp->w_dotline = curwp->w_dotline; wp->w_markline = curwp->w_markline; /* figure out which half of the screen we're in */ ntru = (curwp->w_ntrows - 1) / 2; /* Upper size */ ntrl = (curwp->w_ntrows - 1) - ntru; /* Lower size */ for (lp = curwp->w_linep, ntrd = 0; lp != curwp->w_dotp; lp = lforw(lp)) ntrd++; lp = curwp->w_linep; /* old is upper window */ if (ntrd <= ntru) { /* hit mode line */ if (ntrd == ntru) lp = lforw(lp); curwp->w_ntrows = ntru; wp->w_wndp = curwp->w_wndp; curwp->w_wndp = wp; wp->w_toprow = curwp->w_toprow + ntru + 1; wp->w_ntrows = ntrl; /* old is lower window */ } else { wp1 = NULL; wp2 = wheadp; while (wp2 != curwp) { wp1 = wp2; wp2 = wp2->w_wndp; } if (wp1 == NULL) wheadp = wp; else wp1->w_wndp = wp; wp->w_wndp = curwp; wp->w_toprow = curwp->w_toprow; wp->w_ntrows = ntru; /* mode line */ ++ntru; curwp->w_toprow += ntru; curwp->w_ntrows = ntrl; while (ntru--) lp = lforw(lp); } /* adjust the top lines if necessary */ curwp->w_linep = lp; wp->w_linep = lp; curwp->w_rflag |= WFMODE | WFFULL; wp->w_rflag |= WFMODE | WFFULL; /* if FFOTHARG, set flags) */ if (f & FFOTHARG) wp->w_flag = n; return (TRUE); }
/* ARGSUSED */ int desckey(int f, int n) { KEYMAP *curmap; PF funct; int c, m, i, num; char *pep; char dprompt[80]; #ifndef NO_MACRO if (inmacro) return (TRUE); /* ignore inside keyboard macro */ #endif /* !NO_MACRO */ num = strlcpy(dprompt, "Describe key briefly: ", sizeof(dprompt)); if (num >= sizeof(dprompt)) num = sizeof(dprompt) - 1; pep = dprompt + num; key.k_count = 0; m = curbp->b_nmodes; curmap = curbp->b_modes[m]->p_map; for (;;) { for (;;) { ewprintf("%s", dprompt); pep[-1] = ' '; pep = getkeyname(pep, sizeof(dprompt) - (pep - dprompt), key.k_chars[key.k_count++] = c = getkey(FALSE)); if ((funct = doscan(curmap, c, &curmap)) != NULL) break; *pep++ = '-'; *pep = '\0'; } if (funct != rescan) break; if (ISUPPER(key.k_chars[key.k_count - 1])) { funct = doscan(curmap, TOLOWER(key.k_chars[key.k_count - 1]), &curmap); if (funct == NULL) { *pep++ = '-'; *pep = '\0'; continue; } if (funct != rescan) break; } nextmode: if (--m < 0) break; curmap = curbp->b_modes[m]->p_map; for (i = 0; i < key.k_count; i++) { funct = doscan(curmap, key.k_chars[i], &curmap); if (funct != NULL) { if (i == key.k_count - 1 && funct != rescan) goto found; funct = rescan; goto nextmode; } } *pep++ = '-'; *pep = '\0'; } found: if (funct == rescan || funct == selfinsert) ewprintf("%k is not bound to any function"); else if ((pep = (char *)function_name(funct)) != NULL) ewprintf("%k runs the command %s", pep); else ewprintf("%k is bound to an unnamed function"); return (TRUE); }
/*ARGSUSED*/ spawncli(f, n) { extern char *strrchr(); register int pid; register int wpid; register VOID (*oqsig)(); register VOID (*oisig)(); #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ register VOID (*owsig)(); #endif #ifdef SIGTSTP /* 93.07.08 by S.Yoshida */ register int omask; #endif #endif /* ADDFUNC */ int status = FALSE; int errp = FALSE; #ifdef XKEYS /* 92.03.16 by Gen KUROKI */ ttykeymaptidy(); #endif /* XKEYS */ if (shellp == NULL) { shellp = getenv("SHELL"); if (shellp == NULL) shellp = getenv("shell"); if (shellp == NULL) shellp = "/bin/sh"; /* Safer. */ shname = strrchr( shellp, '/' ); shname = shname ? shname+1 : shellp; } ttcolor(CTEXT); ttnowindow(); #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGTSTP /* 93.07.08 by S.Yoshida */ if (strcmp(shellp, "/bin/csh") == 0) { if (epresf != FALSE) { ttmove(nrow-1, 0); tteeol(); epresf = FALSE; } /* Csh types a "\n" */ ttmove(nrow-2, 0); /* before "Stopped". */ } else { #endif #endif ttmove(nrow-1, 0); if (epresf != FALSE) { tteeol(); epresf = FALSE; } #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGTSTP /* 93.07.08 by S.Yoshida */ } #endif #endif ttclose(); sgarbf = TRUE; /* Force repaint. */ #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGTSTP /* 93.07.08 by S.Yoshida */ # ifdef HAVE_GETSID if (job_control) { # else if (strcmp(shellp, "/bin/sh")!=0 || getenv("BASH_VERSION") || getenv("BASH")) { /* C shell, ksh or bash */ # endif /* omask = sigsetmask(0); */ oqsig = signal(SIGQUIT, SIG_IGN); oisig = signal(SIGINT, SIG_IGN); #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ owsig = signal(SIGWINCH, SIG_IGN); #endif (void) kill(0, SIGTSTP); /* (void) sigsetmask(omask); */ signal(SIGINT, oisig); signal(SIGQUIT, oqsig); #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ signal(SIGWINCH, owsig); #endif } else { /* Bourne shell. */ #endif /* SIGTSTP */ #endif /* ADDFUNC */ oqsig = signal(SIGQUIT, SIG_IGN); oisig = signal(SIGINT, SIG_IGN); #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ owsig = signal(SIGWINCH, SIG_IGN); #endif #endif if ((pid=fork()) == 0) { (void) signal(SIGINT, oisig); (void) signal(SIGQUIT, oqsig); #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ (void) signal(SIGWINCH, owsig); #endif #endif #ifdef EXTD_DIR dirend(); #endif execlp(shellp, shname, "-i", (char *)NULL); _exit(1); /* Should do better! */ } else if (pid > 0) { while ((wpid=wait(&status))>=0 && wpid!=pid) ; } else errp = TRUE; signal(SIGINT, oisig); signal(SIGQUIT, oqsig); #ifdef ADDFUNC /* 93.07.08 by S.Yoshida */ #ifdef SIGWINCH /* 93.07.08 by S.Yoshida */ signal(SIGWINCH, owsig); #endif #ifdef SIGTSTP /* 93.07.08 by S.Yoshida */ } #endif #endif ttopen(); #ifdef SIGWINCH /* by A.ITO 21 Jan. 1991 / by S.Yoshida */ refresh(FFRAND, 0); /* May be resized. */ #endif if(errp) ewprintf("Failed to create process"); #ifdef XKEYS /* 92.03.16 by Gen KUROKI */ ttykeypadstart(); #endif /* XKEYS */ return !( errp | status ); } #ifndef NO_SHELL /* 91.01.10 by K.Maeda */ #include <sys/types.h> #include <sys/stat.h> /* * Call process in subshell. * Execute COMMAND binding standard input to file INPUT. * NULL as INPUT means standard input should be bound to * /dev/null or whatever equivalent in your OS. * All output during the execution (including standard error output) * should go into a scratch file, whose name call_process() returns. * Return value NULL means error in some stage of the execution. * In that case, scratch file should be deleted. */ char * call_process(command, input) char *command; char *input; { char buf[256]; char *tmp; static char tmpbuf[20]; int ostdin, ostdout, ostderr, in, out, s; extern char *mktemp(); strcpy(tmpbuf, "/tmp/ngXXXXXX"); if ((tmp = mktemp(tmpbuf)) == NULL) return NULL; if ((in = open(input ? input : "/dev/null", 0)) < 0) return NULL; if ((out = creat(tmp, S_IREAD | S_IWRITE)) < 0) { close(in); return NULL; } ostdin = dup(0); ostdout = dup(1); ostderr = dup(2); if (ostdin < 0 || ostdout < 0 || ostderr < 0) { s = -1; goto skip; } #ifndef SVR2 /* 91.02.04 SVR3 or later. by Junn Ohta */ dup2(in, 0); dup2(out, 1); dup2(out, 2); #else /* SVR2 */ close(0); dup(in); close(1); dup(out); close(2); dup(out); #endif /* SVR2 */ strcpy(buf, command); #ifdef EXTD_DIR ensurecwd(); #endif s = system(buf); close(in); close(out); #ifndef SVR2 /* 91.02.04 SVR3 or later. by Junn Ohta */ dup2(ostdin, 0); dup2(ostdout, 1); dup2(ostderr, 2); #else /* SVR2 */ close(0); dup(ostdin); close(1); dup(ostdout); close(2); dup(ostderr); #endif /* SVR2 */ skip: close(ostdin); close(ostdout); close(ostderr); if (s == -1) { unlink(tmp); return NULL; } return tmp; }
/* ARGSUSED */ int tagsvisit(int f, int n) { char fname[NFILEN], *bufp, *temp; struct stat sb; if (getbufcwd(fname, sizeof(fname)) == FALSE) fname[0] = '\0'; if (strlcat(fname, DEFAULTFN, sizeof(fname)) >= sizeof(fname)) { dobeep(); ewprintf("Filename too long"); return (FALSE); } bufp = eread("visit tags table (default %s): ", fname, NFILEN, EFFILE | EFCR | EFNEW | EFDEF, DEFAULTFN); if (stat(bufp, &sb) == -1) { dobeep(); ewprintf("stat: %s", strerror(errno)); return (FALSE); } else if (S_ISREG(sb.st_mode) == 0) { dobeep(); ewprintf("Not a regular file"); return (FALSE); } else if (access(bufp, R_OK) == -1) { dobeep(); ewprintf("Cannot access file %s", bufp); return (FALSE); } if (tagsfn == NULL) { if (bufp == NULL) return (ABORT); else if (bufp[0] == '\0') { if ((tagsfn = strdup(fname)) == NULL) { dobeep(); ewprintf("Out of memory"); return (FALSE); } } else { /* bufp points to local variable, so duplicate. */ if ((tagsfn = strdup(bufp)) == NULL) { dobeep(); ewprintf("Out of memory"); return (FALSE); } } } else { if ((temp = strdup(bufp)) == NULL) { dobeep(); ewprintf("Out of memory"); return (FALSE); } free(tagsfn); tagsfn = temp; if (eyorn("Keep current list of tags table also") == FALSE) { ewprintf("Starting a new list of tags table"); unloadtags(); } loaded = FALSE; } return (TRUE); }
int main(int argc, char **argv) { char *cp, *init_fcn_name = NULL; PF init_fcn = NULL; int o, i, nfiles; int nobackups = 0; struct buffer *bp; __progname = argv[0]; while ((o = getopt(argc, argv, "nf:")) != -1) switch (o) { 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; default: usage(); } argc -= optind; argv += optind; maps_init(); /* Keymaps and modes. */ funmap_init(); /* Functions. */ /* * This is where we initialize standalone extensions that should * be loaded dynamically sometime in the future. */ { extern void grep_init(void); extern void theo_init(void); extern void cmode_init(void); extern void dired_init(void); dired_init(); grep_init(); theo_init(); cmode_init(); } if (init_fcn_name && (init_fcn = name_function(init_fcn_name)) == NULL) errx(1, "Unknown function `%s'", init_fcn_name); vtinit(); /* Virtual terminal. */ dirinit(); /* Get current directory. */ edinit(init_fcn); /* Buffers, windows. */ ttykeymapinit(); /* Symbols, bindings. */ /* * doing update() before reading files causes the error messages from * the file I/O show up on the screen. (and also an extra display of * the mode line if there are files specified on the command line.) */ update(); #ifndef NO_STARTUP /* user startup file */ if ((cp = startupfile(NULL)) != NULL) (void)load(cp); #endif /* !NO_STARTUP */ /* * Create scratch buffer now, killing old *init* buffer. * This causes *scratch* to be created and made curbp, * ensuring default modes are inherited from the startup * file correctly */ if ((bp = bfind("*init*", FALSE)) != NULL) killbuffer(bp); /* Force FFOTHARG=1 so that this mode is enabled, not simply toggled */ 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 ((curbp = findbuffer(cp)) == NULL) { vttidy(); errx(1, "Can't find current buffer!"); } (void)showbuffer(curbp, curwp, 0); if (readin(cp) != TRUE) killbuffer(curbp); else { /* Ensure enabled, not just toggled */ if (init_fcn_name) init_fcn(FFOTHARG, 1); nfiles++; } } } } if (nfiles > 2) listbuffers(0, 1); /* fake last flags */ thisflag = 0; for (;;) { if (epresf == KCLEAR) eerase(); if (epresf == TRUE) epresf = KCLEAR; if (winch_flag) { do_redraw(0, 0, TRUE); winch_flag = 0; } update(); lastflag = thisflag; thisflag = 0; switch (doin()) { case TRUE: break; case ABORT: ewprintf("Quit"); /* FALLTHRU */ case FALSE: default: ttbeep(); #ifndef NO_MACRO macrodef = FALSE; #endif /* !NO_MACRO */ } } }
/* * XXX dname needs to have enough place to store an additional '/'. */ struct buffer * dired_(char *dname) { struct buffer *bp; FILE *dirpipe; char line[256]; int len, ret; #ifdef MONA DIR *dirp; struct dirent *dent; char* month_names[] = {"Jan", "Feb" ,"Mar" ,"Apr" ,"May" ,"Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; #endif if ((dname = adjustname(dname, FALSE)) == NULL) { ewprintf("Bad directory name"); return (NULL); } /* this should not be done, instead adjustname() should get a flag */ len = strlen(dname); if (dname[len - 1] != '/') { dname[len++] = '/'; dname[len] = '\0'; } if ((bp = findbuffer(dname)) == NULL) { ewprintf("Could not create buffer"); return (NULL); } if (bclear(bp) != TRUE) return (NULL); bp->b_flag |= BFREADONLY; #ifdef MONA dirp = opendir(dname); assert(dirp); while ((dent = readdir(dirp)) != NULL) { snprintf(line, sizeof(line), "%s/%s", dname, dent->d_name); int year, month, day, hour, min, sec, size; mona_get_file_datetime_size(line, &year, &month, &day, &hour, &min, &sec, &size); char* month_name; if (month <= 12 && month >= 1) { month_name = month_names[month - 1]; } else { // assert(0); month_name = "---"; } snprintf(line, sizeof(line), " %crwxrwxrwx 1 mona mona %d %s %02d %02d:%02d %s", fisdir(line) ? 'd' : '-', size, month_name, day, hour, min, dent->d_name); addline(bp, line); } closedir(dirp); #else #ifdef GNU_LS # ifdef __CYGWIN__ /* On Windows platforms the user or group name can be two * words, such as "Domain Users" or "First Last." So, we must * use the --numeric-uid-gid option of ls, or else we don't * know where the filename starts. */ ret = snprintf(line, sizeof(line), "ls -aln --time-style='+%%b %%d %%H:%%M' '%s'", dname); # else ret = snprintf(line, sizeof(line), "ls -al --time-style='+%%b %%d %%H:%%M' '%s'", dname); # endif #else ret = snprintf(line, sizeof(line), "ls -al '%s'", dname); #endif /* GNU_LS */ if (ret < 0 || ret >= sizeof(line)) { ewprintf("Path too long"); return (NULL); } if ((dirpipe = popen(line, "r")) == NULL) { ewprintf("Problem opening pipe to ls"); return (NULL); } line[0] = line[1] = ' '; while (fgets(&line[2], sizeof(line) - 2, dirpipe) != NULL) { line[strcspn(line, "\n")] = '\0'; /* remove ^J */ (void) addline(bp, line); } if (pclose(dirpipe) == -1) { ewprintf("Problem closing pipe to ls : %s", strerror(errno)); return (NULL); } #endif bp->b_dotp = bfirstlp(bp); (void)strlcpy(bp->b_fname, dname, sizeof(bp->b_fname)); (void)strlcpy(bp->b_cwd, dname, sizeof(bp->b_cwd)); if ((bp->b_modes[1] = name_mode("dired")) == NULL) { bp->b_modes[0] = name_mode("fundamental"); ewprintf("Could not find mode dired"); return (NULL); } bp->b_nmodes = 1; return (bp); }
/* ARGSUSED */ int d_shell_command(int f, int n) { #ifdef MONA ewprintf("shell command is not supported"); return (FALSE); #else char command[512], fname[MAXPATHLEN], buf[BUFSIZ], *bufp, *cp; int infd, fds[2]; pid_t pid; struct sigaction olda, newa; struct buffer *bp; struct mgwin *wp; FILE *fin; bp = bfind("*Shell Command Output*", TRUE); if (bclear(bp) != TRUE) return (ABORT); if (d_makename(curwp->w_dotp, fname, sizeof(fname)) != FALSE) { ewprintf("bad line"); return (ABORT); } command[0] = '\0'; if ((bufp = eread("! on %s: ", command, sizeof(command), EFNEW, basename(fname))) == NULL) return (ABORT); infd = open(fname, O_RDONLY); if (infd == -1) { ewprintf("Can't open input file : %s", strerror(errno)); return (FALSE); } if (pipe(fds) == -1) { ewprintf("Can't create pipe : %s", strerror(errno)); close(infd); return (FALSE); } newa.sa_handler = reaper; newa.sa_flags = 0; if (sigaction(SIGCHLD, &newa, &olda) == -1) { close(infd); close(fds[0]); close(fds[1]); return (ABORT); } pid = fork(); switch (pid) { case -1: ewprintf("Can't fork"); return (ABORT); case 0: close(fds[0]); dup2(infd, STDIN_FILENO); dup2(fds[1], STDOUT_FILENO); dup2(fds[1], STDERR_FILENO); execl("/bin/sh", "sh", "-c", bufp, (char *)NULL); exit(1); break; default: close(infd); close(fds[1]); fin = fdopen(fds[0], "r"); if (fin == NULL) /* "r" is surely a valid mode! */ panic("can't happen"); while (fgets(buf, sizeof(buf), fin) != NULL) { cp = strrchr(buf, '\n'); if (cp == NULL && !feof(fin)) { /* too long a line */ int c; addlinef(bp, "%s...", buf); while ((c = getc(fin)) != EOF && c != '\n') ; continue; } else if (cp) *cp = '\0'; addline(bp, buf); } fclose(fin); close(fds[0]); break; } wp = popbuf(bp); if (wp == NULL) return (ABORT); /* XXX - free the buffer?? */ curwp = wp; curbp = wp->w_bufp; if (sigaction(SIGCHLD, &olda, NULL) == -1) ewprintf("Warning, couldn't reset previous signal handler"); return (TRUE); #endif }
/* ARGSUSED */ int fillpara(int f, int n) { int c; /* current char during scan */ int wordlen; /* length of current word */ int clength; /* position on line during fill */ int i; /* index during word copy */ int eopflag; /* Are we at the End-Of-Paragraph? */ int firstflag; /* first word? (needs no space) */ int newlength; /* tentative new line length */ int eolflag; /* was at end of line */ int retval; /* return value */ struct line *eopline; /* pointer to line just past EOP */ char wbuf[MAXWORD]; /* buffer for current word */ if (n == 0) return (TRUE); undo_boundary_enable(FFRAND, 0); /* record the pointer to the line just past the EOP */ (void)gotoeop(FFRAND, 1); if (curwp->w_doto != 0) { /* paragraph ends at end of buffer */ (void)lnewline(); eopline = lforw(curwp->w_dotp); } else eopline = curwp->w_dotp; /* and back top the beginning of the paragraph */ (void)gotobop(FFRAND, 1); /* initialize various info */ while (inword() == 0 && forwchar(FFRAND, 1)); clength = curwp->w_doto; wordlen = 0; /* scan through lines, filling words */ firstflag = TRUE; eopflag = FALSE; while (!eopflag) { /* get the next character in the paragraph */ if ((eolflag = (curwp->w_doto == llength(curwp->w_dotp)))) { c = ' '; if (lforw(curwp->w_dotp) == eopline) eopflag = TRUE; } else c = lgetc(curwp->w_dotp, curwp->w_doto); /* and then delete it */ if (ldelete((RSIZE) 1, KNONE) == FALSE && !eopflag) { retval = FALSE; goto cleanup; } /* if not a separator, just add it in */ if (c != ' ' && c != '\t') { if (wordlen < MAXWORD - 1) wbuf[wordlen++] = c; else { /* * You lose chars beyond MAXWORD if the word * is too long. I'm too lazy to fix it now; it * just silently truncated the word before, * so I get to feel smug. */ ewprintf("Word too long!"); } } else if (wordlen) { /* calculate tentative new length with word added */ newlength = clength + 1 + wordlen; /* * if at end of line or at doublespace and previous * character was one of '.','?','!' doublespace here. * behave the same way if a ')' is preceded by a * [.?!] and followed by a doublespace. */ if ((eolflag || curwp->w_doto == llength(curwp->w_dotp) || (c = lgetc(curwp->w_dotp, curwp->w_doto)) == ' ' || c == '\t') && (ISEOSP(wbuf[wordlen - 1]) || (wbuf[wordlen - 1] == ')' && wordlen >= 2 && ISEOSP(wbuf[wordlen - 2]))) && wordlen < MAXWORD - 1) wbuf[wordlen++] = ' '; /* at a word break with a word waiting */ if (newlength <= fillcol) { /* add word to current line */ if (!firstflag) { (void)linsert(1, ' '); ++clength; } firstflag = FALSE; } else { if (curwp->w_doto > 0 && lgetc(curwp->w_dotp, curwp->w_doto - 1) == ' ') { curwp->w_doto -= 1; (void)ldelete((RSIZE) 1, KNONE); } /* start a new line */ (void)lnewline(); clength = 0; } /* and add the word in in either case */ for (i = 0; i < wordlen; i++) { (void)linsert(1, wbuf[i]); ++clength; } wordlen = 0; } } /* and add a last newline for the end of our new paragraph */ (void)lnewline(); /* * We really should wind up where we started, (which is hard to keep * track of) but I think the end of the last line is better than the * beginning of the blank line. */ (void)backchar(FFRAND, 1); retval = TRUE; cleanup: undo_boundary_enable(FFRAND, 1); return (retval); }
int main(int argc, char **argv) { char *cp, *init_fcn_name = NULL; PF init_fcn = NULL; int o, i, nfiles; int nobackups = 0; struct buffer *bp = NULL; while ((o = getopt(argc, argv, "nf:")) != -1) switch (o) { 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; default: usage(); } argc -= optind; argv += optind; setlocale(LC_CTYPE, ""); maps_init(); /* Keymaps and modes. */ funmap_init(); /* Functions. */ /* * This is where we initialize standalone extensions that should * be loaded dynamically sometime in the future. */ { extern void grep_init(void); extern void theo_init(void); extern void cmode_init(void); extern void dired_init(void); dired_init(); grep_init(); theo_init(); cmode_init(); } if (init_fcn_name && (init_fcn = name_function(init_fcn_name)) == NULL) errx(1, "Unknown function `%s'", init_fcn_name); vtinit(); /* Virtual terminal. */ dirinit(); /* Get current directory. */ edinit(bp); /* Buffers, windows. */ ttykeymapinit(); /* Symbols, bindings. */ bellinit(); /* Audible and visible bell. */ /* * doing update() before reading files causes the error messages from * the file I/O show up on the screen. (and also an extra display of * the mode line if there are files specified on the command line.) */ update(CMODE); /* user startup file. */ if ((cp = startupfile(NULL)) != NULL) (void)load(cp); /* * Now ensure any default buffer modes from the startup file are * given to any files opened when parsing the startup file. * Note *scratch* will also be updated. */ 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]; } } /* Force FFOTHARG=1 so that this mode is enabled, not simply toggled */ 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 ((curbp = findbuffer(cp)) == NULL) { vttidy(); errx(1, "Can't find current buffer!"); } (void)showbuffer(curbp, curwp, 0); if (readin(cp) != TRUE) killbuffer(curbp); else { /* Ensure enabled, not just toggled */ if (init_fcn_name) init_fcn(FFOTHARG, 1); nfiles++; } } } } if (nfiles > 2) listbuffers(0, 1); /* fake last flags */ 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"); /* FALLTHRU */ case FALSE: default: if (!donebell) dobeep(); macrodef = FALSE; } donebell = 0; } }