int execprg(int f, int n) { #ifndef WINNT int s; char line[NLINE]; #endif /* don't allow this command if restricted */ if (restflag) return resterr(); #if WINNT mlwrite("(unsupported)"); return FALSE; #endif #if VMS if ((s = mlreply("!", line, NLINE)) != TRUE) return s; TTflush(); s = sys(line); /* Run the command. */ mlputs("\r\n\n(End)"); /* Pause. */ TTflush(); tgetc(); sgarbf = TRUE; return s; #endif #if MSDOS if ((s = mlreply("$", line, NLINE)) != TRUE) return s; movecursor(term.t_nrow, 0); TTkclose(); execprog(line); TTkopen(); /* if we are interactive, pause here */ if (clexec == FALSE) { mlputs("\r\n(End)"); tgetc(); } sgarbf = TRUE; return TRUE; #endif #if V7 | USG | BSD if ((s = mlreply("!", line, NLINE)) != TRUE) return s; TTputc('\n'); /* Already have '\r' */ TTflush(); TTclose(); /* stty to old modes */ TTkclose(); system(line); fflush(stdout); /* to be sure P.K. */ TTopen(); mlputs("(End)"); /* Pause. */ TTflush(); while ((s = tgetc()) != '\r' && s != ' '); sgarbf = TRUE; return TRUE; #endif }
void vttidy() { mlerase(); movecursor(term.t_nrow, 0); TTflush(); TTclose(); TTkclose(); }
/* ARGSUSED */ int spawncli(int f, int n) { /* i never thought i'd see an ifdef like this one... strange bedfellows */ #if DISP_X11 || SYS_WIN31 mlforce("[This version of vile cannot spawn an interactive shell]"); return FALSE; #else #if SYS_UNIX bottomleft(); ttclean(TRUE); TTputc('\n'); (void)system_SHELL((char *)0); TTflush(); ttunclean(); sgarbf = TRUE; return AfterShell(); #endif /* SYS_UNIX */ #if SYS_VMS bottomleft(); mlforce("[Starting DCL]\r\n"); TTflush(); /* Ignore "ttcol". */ sgarbf = TRUE; return sys(NULL); /* NULL => DCL. */ #endif #if SYS_MSDOS || SYS_OS2 || SYS_WINNT bottomleft(); TTflush(); TTkclose(); { char *shell; if ((shell = getenv("COMSPEC")) == NULL) { #if SYS_OS2 shell = "cmd.exe"; #else shell = "command.com"; #endif system(shell); /* Will search path */ } else { #if SYS_OS2 /* * spawn it if we know it. Some 3rd party command processors fail * if they system themselves (eg 4OS2). CCM 24-MAR-94 */ spawnl( P_WAIT, shell, shell, NULL); #else system(shell); #endif } } TTkopen(); sgarbf = TRUE; return AfterShell(); #endif #endif }
/* * Clean up the virtual terminal system, in anticipation for a return to the * operating system. Move down to the last line and clear it out (the next * system prompt will be written in the line). Shut down the channel to the * terminal. */ void vttidy(void) { mlerase(); movecursor(term.t_nrow, 0); TTflush(); TTclose(); TTkclose(); #ifdef PKCODE write(1, "\r", 1); #endif }
// Clean up the virtual terminal system, in anticipation for a return to the operating system. Move down to the last line and // clear it out (the next system prompt will be written in the line). Shut down the channel to the terminal. Return status. int vttidy(bool force) { // Don't close it if it ain't open. if(opflags & OPVTOPEN) { mlerase(MLFORCE); if((TTflush() == SUCCESS || force) && (TTclose() == SUCCESS || force)) (void) TTkclose(); opflags &= ~OPVTOPEN; } return rc.status; }
/* * Create a subjob with a copy of the command intrepreter in it. When the * command interpreter exits, mark the screen as garbage so that you do a full * repaint. Bound to "^X C". The message at the start in VMS puts out a newline. * Under some (unknown) condition, you don't get one free when DCL starts up. */ spawncli(f, n) { /* don't allow this command if restricted */ if (restflag) return(resterr()); movecursor(term.t_nrow, 0); /* Seek to last line. */ TTflush(); TTkclose(); shell(); TTkopen(); sgarbf = TRUE; return(TRUE); }
execprg(f, n) { register int s; char line[NLINE]; /* don't allow this command if restricted */ if (restflag) return(resterr()); if ((s=mlreply("$", line, NLINE)) != TRUE) return(s); movecursor(term.t_nrow - 1, 0); TTkclose(); execprog(line); TTkopen(); /* if we are interactive, pause here */ if (clexec == FALSE) { puts(TEXT6); /* "\r\n\n[End]" */ tgetc(); } sgarbf = TRUE; return (TRUE); }
/* * filter a buffer through an external DOS program * Bound to ^X # * We use unique temporary file names so that multiple instances of * MicroEMACS don't try to use the same file. */ filter(f, n) { register int s; /* return status from CLI */ register BUFFER *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ char tmpnam[NFILEN]; /* place to store real file name */ char *tmp; /* ptr to TMP DOS environment variable */ static char filnam1[NSTRING]; static char filnam2[NSTRING]; /* don't allow this command if restricted */ if (restflag) return(resterr()); if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ /* get the filter name and its args */ if ((s=mlreply("#", line, NLINE)) != TRUE) return(s); /* Call mktemp() to get unique filenames in the tmp directory. */ if ((tmp = getenv("TMP")) == NULL) filnam1[0] = filnam2[0] = 0; else { strcpy(filnam1, tmp); strcpy(filnam2, tmp); if (filnam1[strlen(filnam1) - 1] != '\\') { strcat(filnam1, "\\"); strcat(filnam2, "\\"); } } strcat(filnam1,"eXXXXXX"); strcat(filnam2,"eXXXXXX"); mktemp(filnam1); /* setup the proper file names */ bp = curbp; strcpy(tmpnam, bp->b_fname); /* save the original name */ strcpy(bp->b_fname, filnam1); /* set it to our new one */ /* write it out, checking for errors */ if (writeout(filnam1, "w") != TRUE) { mlwrite(TEXT2); /* "[Cannot write filter file]" */ strcpy(bp->b_fname, tmpnam); return(FALSE); } mktemp(filnam2); strcat(line, " <"); /* construct the command line */ strcat(line, filnam1); strcat(line, " >"); strcat(line, filnam2); movecursor(term.t_nrow - 1, 0); TTkclose(); system(line); TTkopen(); sgarbf = TRUE; s = TRUE; /* on failure, escape gracefully */ if (s != TRUE || (readin(filnam2,FALSE) == FALSE)) { mlwrite(TEXT3); /* "[Execution failed]" */ strcpy(bp->b_fname, tmpnam); unlink(filnam1); unlink(filnam2); return(s); } /* reset file name */ strcpy(bp->b_fname, tmpnam); /* restore name */ bp->b_flag |= BFCHG; /* flag it as changed */ /* and get rid of the temporary file */ unlink(filnam1); unlink(filnam2); return(TRUE); }
/* * Pipe a one line command into a window * Bound to ^X @ * We use a unique temporary file name so that multiple instances of * MicroEMACS don't try to use the same file. */ pipecmd(f, n) { register WINDOW *wp; /* pointer to new window */ register BUFFER *bp; /* pointer to buffer to zot */ register char *tmp; /* ptr to TMP DOS environment variable */ char line[NLINE]; /* command line send to shell */ static char bname[] = "command"; static char filnam[NSTRING]; char *getenv(); /* don't allow this command if restricted */ if (restflag) return(resterr()); /* get rid of the command output buffer if it exists */ if ((bp=bfind(bname, FALSE, 0)) != FALSE) { /* try to make sure we are off screen */ wp = wheadp; while (wp != NULL) { if (wp->w_bufp == bp) { onlywind(FALSE, 1); break; } wp = wp->w_wndp; } /* get rid of the existing command buffer */ if (zotbuf(bp) != TRUE) return(FALSE); } /* get the command to pipe in */ if (mlreply("@", line, NLINE) != TRUE) return(FALSE); /* Call mktemp() to get a unique filename in the tmp directory. */ if ((tmp = getenv("TMP")) == NULL) filnam[0] = 0; else { strcpy(filnam, tmp); if (filnam[strlen(filnam) - 1] != '\\') strcat(filnam, "\\"); } strcat(filnam,"eXXXXXX"); mktemp(filnam); /* redirect the command output to the output file */ strcat(line, " >>"); strcat(line, filnam); movecursor(term.t_nrow - 1, 0); /* execute the command */ TTkclose(); system(line); TTkopen(); sgarbf = TRUE; /* did the output file get generated? */ if (access( filnam, 0) != 0) return(FALSE); /* split the current window to make room for the command output */ if (splitwind(FALSE, 1) == FALSE) return(FALSE); /* and read the stuff in */ if (getfile(filnam, FALSE) == FALSE) return(FALSE); /* rename the buffer */ strcpy( curwp->w_bufp->b_bname, "command"); /* make this window in VIEW mode, update all mode lines */ curwp->w_bufp->b_mode |= MDVIEW; wp = wheadp; while (wp != NULL) { wp->w_flag |= WFMODE; wp = wp->w_wndp; } /* and get rid of the temporary file */ unlink(filnam); return(TRUE); }
/* the #ifdefs have been totally separated, for readability */ static int spawn1(int rerun, int pressret) { #if DISP_IBMPC int closed; #endif #if COMMON_SH_PROMPT register int s; char line[NLINE]; /* command line send to shell */ if ((s = ShellPrompt(&save_shell[0], line, rerun)) != TRUE) return s; #endif /* COMMON_SH_PROMPT */ /* take care of autowrite */ if (writeall(FALSE,1,FALSE,TRUE,TRUE) != TRUE) return FALSE; #if SYS_UNIX #if DISP_X11 (void)system_SHELL(line); #else ttclean(TRUE); (void)system_SHELL(line); TTflush(); ttunclean(); if (pressret) pressreturn(); TTopen(); TTkopen(); TTflush(); sgarbf = TRUE; #endif /* DISP_X11 */ return AfterShell(); #endif /* SYS_UNIX */ #if SYS_VMS TTputc('\n'); /* Already have '\r' */ TTflush(); s = sys(line); /* Run the command. */ mlforce("\r\n\n[End]"); /* Pause. */ TTflush(); (void)keystroke(); sgarbf = TRUE; return (s); #endif #if SYS_WIN31 mlforce("[Not in Windows 3.1]"); return FALSE; #endif #if SYS_MSDOS || SYS_OS2 || SYS_WINNT bottomleft(); TTputc('\n'); TTflush(); TTkclose(); #if DISP_IBMPC /* If we don't reset to 80x25, parts of the shell-output will go * astray. */ closed = term.t_ncol != 80 || term.t_nrow != 25; if (closed) TTclose(); #endif system(line); TTkopen(); /* if we are interactive, pause here */ if (pressret) { pressreturn(); } #if DISP_IBMPC /* Reopen the display _after_ the prompt, to keep the shell-output * in the same type of screen as the prompt. */ if (closed) TTopen(); #endif sgarbf = TRUE; return AfterShell(); #endif }
/* * This is the general command execution routine. It handles the fake binding * of all the keys to "self-insert". It also clears out the "thisflag" word, * and arranges to move it to the "lastflag", so that the next command can * look at it. Return the status of command. */ int execute(int c, int f, int n) { int status; fn_t execfunc; /* if the keystroke is a bound function...do it */ execfunc = getbind(c); if (execfunc != NULL) { thisflag = 0; status = (*execfunc) (f, n); lastflag = thisflag; return status; } /* * If a space was typed, fill column is defined, the argument is non- * negative, wrap mode is enabled, and we are now past fill column, * and we are not read-only, perform word wrap. */ if (c == ' ' && (curwp->w_bufp->b_mode & MDWRAP) && fillcol > 0 && n >= 0 && getccol(FALSE) > fillcol && (curwp->w_bufp->b_mode & MDVIEW) == FALSE) execute(META | SPEC | 'W', FALSE, 1); #if PKCODE if ((c >= 0x20 && c <= 0x7E) /* Self inserting. */ #if IBMPC || (c >= 0x80 && c <= 0xFE)) { #else #if VMS || BSD || USG /* 8BIT P.K. */ || (c >= 0xA0 && c <= 0xFFFF)) { #else ) { #endif #endif #else if ((c >= 0x20 && c <= 0xFF)) { /* Self inserting. */ #endif if (n <= 0) { /* Fenceposts. */ lastflag = 0; return n < 0 ? FALSE : TRUE; } thisflag = 0; /* For the future. */ /* if we are in overwrite mode, not at eol, and next char is not a tab or we are at a tab stop, delete a char forword */ if (curwp->w_bufp->b_mode & MDOVER && curwp->w_doto < curwp->w_dotp->l_used && (lgetc(curwp->w_dotp, curwp->w_doto) != '\t' || (curwp->w_doto) % 8 == 7)) ldelchar(1, FALSE); /* do the appropriate insertion */ if (c == '}' && (curbp->b_mode & MDCMOD) != 0) status = insbrace(n, c); else if (c == '#' && (curbp->b_mode & MDCMOD) != 0) status = inspound(); else status = linsert(n, c); #if CFENCE /* check for CMODE fence matching */ if ((c == '}' || c == ')' || c == ']') && (curbp->b_mode & MDCMOD) != 0) fmatch(c); #endif /* check auto-save mode */ if (curbp->b_mode & MDASAVE) if (--gacount == 0) { /* and save the file if needed */ upscreen(FALSE, 0); filesave(FALSE, 0); gacount = gasave; } lastflag = thisflag; return status; } TTbeep(); mlwrite("(Key not bound)"); /* complain */ lastflag = 0; /* Fake last flags. */ return FALSE; } /* * Fancy quit command, as implemented by Norm. If the any buffer has * changed do a write on that buffer and exit emacs, otherwise simply exit. */ int quickexit(int f, int n) { struct buffer *bp; /* scanning pointer to buffers */ struct buffer *oldcb; /* original current buffer */ int status; oldcb = curbp; /* save in case we fail */ bp = bheadp; while (bp != NULL) { if ((bp->b_flag & BFCHG) != 0 /* Changed. */ && (bp->b_flag & BFTRUNC) == 0 /* Not truncated P.K. */ && (bp->b_flag & BFINVS) == 0) { /* Real. */ curbp = bp; /* make that buffer cur */ mlwrite("(Saving %s)", bp->b_fname); #if PKCODE #else mlwrite("\n"); #endif if ((status = filesave(f, n)) != TRUE) { curbp = oldcb; /* restore curbp */ return status; } } bp = bp->b_bufp; /* on to the next buffer */ } quit(f, n); /* conditionally quit */ return TRUE; } static void emergencyexit(int signr) { quickexit(FALSE, 0); quit(TRUE, 0); } /* * Quit command. If an argument, always quit. Otherwise confirm if a buffer * has been changed and not written out. Normally bound to "C-X C-C". */ int quit(int f, int n) { int s; if (f != FALSE /* Argument forces it. */ || anycb() == FALSE /* All buffers clean. */ /* User says it's OK. */ || (s = mlyesno("Modified buffers exist. Leave anyway")) == TRUE) { #if (FILOCK && BSD) || SVR4 if (lockrel() != TRUE) { TTputc('\n'); TTputc('\r'); TTclose(); TTkclose(); exit(1); } #endif vttidy(); if (f) exit(n); else exit(GOOD); } mlwrite(""); return s; } /* * Begin a keyboard macro. * Error if not at the top level in keyboard processing. Set up variables and * return. */ int ctlxlp(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } mlwrite("(Start macro)"); kbdptr = &kbdm[0]; kbdend = kbdptr; kbdmode = RECORD; return TRUE; } /* * End keyboard macro. Check for the same limit conditions as the above * routine. Set up the variables and return to the caller. */ int ctlxrp(int f, int n) { if (kbdmode == STOP) { mlwrite("%%Macro not active"); return FALSE; } if (kbdmode == RECORD) { mlwrite("(End macro)"); kbdmode = STOP; } return TRUE; } /* * Execute a macro. * The command argument is the number of times to loop. Quit as soon as a * command gets an error. Return TRUE if all ok, else FALSE. */ int ctlxe(int f, int n) { if (kbdmode != STOP) { mlwrite("%%Macro already active"); return FALSE; } if (n <= 0) return TRUE; kbdrep = n; /* remember how many times to execute */ kbdmode = PLAY; /* start us in play mode */ kbdptr = &kbdm[0]; /* at the beginning */ return TRUE; } /* * Abort. * Beep the beeper. Kill off any keyboard macro, etc., that is in progress. * Sometimes called as a routine, to do general aborting of stuff. */ int ctrlg(int f, int n) { TTbeep(); kbdmode = STOP; mlwrite("(Aborted)"); return ABORT; }
/* * Create a subjob with a copy of the command intrepreter in it. When the * command interpreter exits, mark the screen as garbage so that you do a full * repaint. Bound to "^X C". The message at the start in VMS puts out a newline. * Under some (unknown) condition, you don't get one free when DCL starts up. */ int spawncli(int f, int n) { #if V7 | USG | BSD char *cp; #endif /* don't allow this command if restricted */ if (restflag) return resterr(); #if WINNT mlwrite("(unsupported)"); return FALSE; #endif #if VMS movecursor(term.t_nrow, 0); /* In last line. */ mlputs("(Starting DCL)\r\n"); TTflush(); /* Ignore "ttcol". */ sgarbf = TRUE; sys(NULL); sleep(1); mlputs("\r\n(Returning from DCL)\r\n"); TTflush(); sleep(1); return TRUE; #endif #if MSDOS & (MSC | TURBO) movecursor(term.t_nrow, 0); /* Seek to last line. */ TTflush(); TTkclose(); shellprog(""); TTkopen(); sgarbf = TRUE; return TRUE; #endif #if V7 | USG | BSD movecursor(term.t_nrow, 0); /* Seek to last line. */ TTflush(); TTclose(); /* stty to old settings */ TTkclose(); /* Close "keyboard" */ if ((cp = getenv("SHELL")) != NULL && *cp != '\0') system(cp); else #if BSD system("exec /bin/csh"); #else system("exec /bin/sh"); #endif sgarbf = TRUE; sleep(2); TTopen(); TTkopen(); #ifdef SIGWINCH /* * This fools the update routines to force a full * redraw with complete window size checking. * -lbt */ chg_width = term.t_ncol; chg_height = term.t_nrow + 1; term.t_nrow = term.t_ncol = 0; #endif return TRUE; #endif }
/* * filter a buffer through an external DOS program * Bound to ^X # */ int filter_buffer(int f, int n) { int s; /* return status from CLI */ struct buffer *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ char tmpnam[NFILEN]; /* place to store real file name */ static char bname1[] = "fltinp"; static char filnam1[] = "fltinp"; static char filnam2[] = "fltout"; /* don't allow this command if restricted */ if (restflag) return resterr(); if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ #if VMS mlwrite("Not available under VMS"); return FALSE; #endif /* get the filter name and its args */ if ((s = mlreply("#", line, NLINE)) != TRUE) return s; /* setup the proper file names */ bp = curbp; xstrcpy(tmpnam, bp->b_fname); /* save the original name */ xstrcpy(bp->b_fname, bname1); /* set it to our new one */ /* write it out, checking for errors */ if (writeout(filnam1) != TRUE) { mlwrite("(Cannot write filter file)"); xstrcpy(bp->b_fname, tmpnam); return FALSE; } #if MSDOS strcat(line, " <fltinp >fltout"); movecursor(term.t_nrow - 1, 0); TTkclose(); shellprog(line); TTkopen(); sgarbf = TRUE; s = TRUE; #endif #if V7 | USG | BSD TTputc('\n'); /* Already have '\r' */ TTflush(); TTclose(); /* stty to old modes */ TTkclose(); strcat(line, " <fltinp >fltout"); system(line); TTopen(); TTkopen(); TTflush(); sgarbf = TRUE; s = TRUE; #endif /* on failure, escape gracefully */ if (s != TRUE || (readin(filnam2, FALSE) == FALSE)) { mlwrite("(Execution failed)"); xstrcpy(bp->b_fname, tmpnam); unlink(filnam1); unlink(filnam2); return s; } /* reset file name */ xstrcpy(bp->b_fname, tmpnam); /* restore name */ bp->b_flag |= BFCHG; /* flag it as changed */ /* and get rid of the temporary file */ unlink(filnam1); unlink(filnam2); return TRUE; }
/* * Pipe a one line command into a window * Bound to ^X @ */ int pipecmd(int f, int n) { int s; /* return status from CLI */ struct window *wp; /* pointer to new window */ struct buffer *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ static char bname[] = "command"; static char filnam[NSTRING] = "command"; #if MSDOS char *tmp; FILE *fp; int len; #endif /* don't allow this command if restricted */ if (restflag) return resterr(); #if MSDOS if ((tmp = getenv("TMP")) == NULL && (tmp = getenv("TEMP")) == NULL) xstrcpy(filnam, "command"); else { xstrcpy(filnam, tmp); len = strlen(tmp); if (len <= 0 || filnam[len - 1] != '\\' && filnam[len - 1] != '/') strcat(filnam, "\\"); strcat(filnam, "command"); } #endif #if VMS mlwrite("Not available under VMS"); return FALSE; #endif /* get the command to pipe in */ if ((s = mlreply("@", line, NLINE)) != TRUE) return s; /* get rid of the command output buffer if it exists */ if ((bp = bfind(bname, FALSE, 0)) != FALSE) { /* try to make sure we are off screen */ wp = wheadp; while (wp != NULL) { if (wp->w_bufp == bp) { #if PKCODE if (wp == curwp) delwind(FALSE, 1); else onlywind(FALSE, 1); break; #else onlywind(FALSE, 1); break; #endif } wp = wp->w_wndp; } if (zotbuf(bp) != TRUE) return FALSE; } #if MSDOS strcat(line, " >>"); strcat(line, filnam); movecursor(term.t_nrow, 0); TTkclose(); shellprog(line); TTkopen(); sgarbf = TRUE; if ((fp = fopen(filnam, "r")) == NULL) { s = FALSE; } else { fclose(fp); s = TRUE; } #endif #if V7 | USG | BSD TTflush(); TTclose(); /* stty to old modes */ TTkclose(); strcat(line, ">"); strcat(line, filnam); system(line); TTopen(); TTkopen(); TTflush(); sgarbf = TRUE; s = TRUE; #endif if (s != TRUE) return s; /* split the current window to make room for the command output */ if (splitwind(FALSE, 1) == FALSE) return FALSE; /* and read the stuff in */ if (getfile(filnam, FALSE) == FALSE) return FALSE; /* make this window in VIEW mode, update all mode lines */ curwp->w_bufp->b_mode |= MDVIEW; wp = wheadp; while (wp != NULL) { wp->w_flag |= WFMODE; wp = wp->w_wndp; } /* and get rid of the temporary file */ unlink(filnam); return TRUE; }