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); TTputc('\n'); /* Already have '\r' */ TTflush(); TTclose(); /* stty to old modes */ system(line); TTopen(); mlputs(TEXT188); /* Pause. */ /* "[End]" */ TTflush(); while ((s = tgetc()) != '\r' && s != ' ') ; sgarbf = TRUE; return(TRUE); }
/* * Run a one-liner in a subjob. When the command returns, wait for a single * character to be typed, then mark the screen as garbage so a full repaint is * done. Bound to "C-X !". */ spawn(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); TTputc('\n'); /* Already have '\r' */ TTflush(); TTclose(); /* stty to old modes */ system(line); TTopen(); TTflush(); /* if we are interactive, pause here */ if (clexec == FALSE) { mlputs(TEXT6); /* "\r\n\n[End]" */ tgetc(); } sgarbf = TRUE; return(TRUE); }
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 }
/* 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 }
void pressreturn(void) { int c; int odiscmd; odiscmd = discmd; discmd = TRUE; mlprompt("[Press return to continue]"); discmd = odiscmd; TTflush(); /* loop for a CR, a space, or a : to do another named command */ while ((c = keystroke()) != '\r' && c != '\n' && c != ' ' && !ABORTED(c)) { if (kcod2fnc(c) == &f_namedcmd) { unkeystroke(c); break; } } TTputc('\r'); TTputc('\n'); }
/* 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; }
/* * Pipe a one line command into a window * Bound to ^X @ */ pipecmd(f, n) { register int s; /* return status from CLI */ register WINDOW *wp; /* pointer to new window */ register BUFFER *bp; /* pointer to buffer to zot */ char line[NLINE]; /* command line send to shell */ static char bname[] = "command"; static char filnam[NFILEN] = "command"; /* don't allow this command if restricted */ if (restflag) return(resterr()); /* 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) { onlywind(FALSE, 1); break; } wp = wp->w_wndp; } if (zotbuf(bp) != TRUE) return(FALSE); } TTputc('\n'); /* Already have '\r' */ TTflush(); TTclose(); /* stty to old modes */ strcat(line,">"); strcat(line,filnam); system(line); TTopen(); TTflush(); sgarbf = TRUE; s = TRUE; 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); }
/* * updateline() * * int row; row of screen to update * struct video *vp1; virtual screen image * struct video *vp2; physical screen image */ static int updateline(int row, struct video *vp1, struct video *vp2) { #if RAINBOW /* UPDATELINE specific code for the DEC rainbow 100 micro */ unicode_t *cp1; unicode_t *cp2; int nch; /* since we don't know how to make the rainbow do this, turn it off */ flags &= (~VFREV & ~VFREQ); cp1 = &vp1->v_text[0]; /* Use fast video. */ cp2 = &vp2->v_text[0]; putline(row + 1, 1, cp1); nch = term.t_ncol; do { *cp2 = *cp1; ++cp2; ++cp1; } while (--nch); *flags &= ~VFCHG; #else /* UPDATELINE code for all other versions */ unicode_t *cp1; unicode_t *cp2; unicode_t *cp3; unicode_t *cp4; unicode_t *cp5; int nbflag; /* non-blanks to the right flag? */ int rev; /* reverse video flag */ int req; /* reverse video request flag */ /* set up pointers to virtual and physical lines */ cp1 = &vp1->v_text[0]; cp2 = &vp2->v_text[0]; #if COLOR TTforg(vp1->v_rfcolor); TTbacg(vp1->v_rbcolor); #endif #if REVSTA | COLOR /* if we need to change the reverse video status of the current line, we need to re-write the entire line */ rev = (vp1->v_flag & VFREV) == VFREV; req = (vp1->v_flag & VFREQ) == VFREQ; if ((rev != req) #if COLOR || (vp1->v_fcolor != vp1->v_rfcolor) || (vp1->v_bcolor != vp1->v_rbcolor) #endif ) { movecursor(row, 0); /* Go to start of line. */ /* set rev video if needed */ if (rev != req) (*term.t_rev) (req); /* scan through the line and dump it to the screen and the virtual screen array */ cp3 = &vp1->v_text[term.t_ncol]; while (cp1 < cp3) { TTputc(*cp1); ++ttcol; *cp2++ = *cp1++; } /* turn rev video off */ if (rev != req) (*term.t_rev) (FALSE); /* update the needed flags */ vp1->v_flag &= ~VFCHG; if (req) vp1->v_flag |= VFREV; else vp1->v_flag &= ~VFREV; #if COLOR vp1->v_fcolor = vp1->v_rfcolor; vp1->v_bcolor = vp1->v_rbcolor; #endif return TRUE; } #endif /* advance past any common chars at the left */ while (cp1 != &vp1->v_text[term.t_ncol] && cp1[0] == cp2[0]) { ++cp1; ++cp2; } /* This can still happen, even though we only call this routine on changed * lines. A hard update is always done when a line splits, a massive * change is done, or a buffer is displayed twice. This optimizes out most * of the excess updating. A lot of computes are used, but these tend to * be hard operations that do a lot of update, so I don't really care. */ /* if both lines are the same, no update needs to be done */ if (cp1 == &vp1->v_text[term.t_ncol]) { vp1->v_flag &= ~VFCHG; /* flag this line is changed */ return TRUE; } /* find out if there is a match on the right */ nbflag = FALSE; cp3 = &vp1->v_text[term.t_ncol]; cp4 = &vp2->v_text[term.t_ncol]; while (cp3[-1] == cp4[-1]) { --cp3; --cp4; if (cp3[0] != ' ') /* Note if any nonblank */ nbflag = TRUE; /* in right match. */ } cp5 = cp3; /* Erase to EOL ? */ if (nbflag == FALSE && eolexist == TRUE && (req != TRUE)) { while (cp5 != cp1 && cp5[-1] == ' ') --cp5; if (cp3 - cp5 <= 3) /* Use only if erase is */ cp5 = cp3; /* fewer characters. */ } movecursor(row, cp1 - &vp1->v_text[0]); /* Go to start of line. */ #if REVSTA TTrev(rev); #endif while (cp1 != cp5) { /* Ordinary. */ TTputc(*cp1); ++ttcol; *cp2++ = *cp1++; } if (cp5 != cp3) { /* Erase. */ TTeeol(); while (cp1 != cp3) *cp2++ = *cp1++; } #if REVSTA TTrev(FALSE); #endif vp1->v_flag &= ~VFCHG; /* flag this line as updated */ return TRUE; #endif }
// Update a single line on the physical screen, given row, virtual screen image, and physical screen image. This does not know // how to use insert or delete character sequences; we are using VT52 functionality. Update the physical row and column // variables. It does try to exploit erase to end of line. Return status. static int pupd_line(int row,Video *vp,Video *pp) { char *vir_left; // Left pointer to virtual line. char *phy_left; // Left pointer to physical line. char *vir_right; // Right pointer to virtual line. char *phy_right; // Right pointer to physical line. int rev_left; // Leftmost reversed char index. int rev_right; // Rightmost reversed char index. char *left_blank; // Left-most trailing blank. int non_blanks; // Non-blanks to the right flag. int update_column; // Update column. int old_rev_state = false; // Reverse video states. int new_rev_state; // Set up pointers to virtual and physical lines. vir_left = vp->v_text; vir_right = vp->v_text + term.t_ncol; phy_left = pp->v_text; phy_right = pp->v_text + term.t_ncol; update_column = 0; rev_left = FARRIGHT; rev_right = 0; non_blanks = true; // If this is a legitimate line to optimize. if(!(pp->v_flags & VFNEW)) { // Advance past any common chars at the left. while(vir_left != vp->v_text + term.t_ncol && vir_left[0] == phy_left[0]) { ++vir_left; ++update_column; ++phy_left; } // Advance past any common chars at the right. non_blanks = false; while(vir_right[-1] == phy_right[-1] && vir_right >= vir_left) { --vir_right; --phy_right; // Note if any nonblank in right match. if(vir_right[0] != ' ') non_blanks = true; } } #if COLOR // New line color? if(vp->v_rfcolor != vp->v_fcolor || vp->v_rbcolor != vp->v_bcolor) { vp->v_fcolor = vp->v_rfcolor; vp->v_bcolor = vp->v_rbcolor; vp->v_flags &= ~VFCOLOR; vir_left = vp->v_text; vir_right = vp->v_text + term.t_ncol; phy_left = pp->v_text; phy_right = pp->v_text + term.t_ncol; update_column = 0; } if(TTforg(vp->v_fcolor) != SUCCESS || TTbacg(vp->v_bcolor) != SUCCESS) return rc.status; #endif // Reverse video changes? if(vp->v_left != pp->v_left || vp->v_right != pp->v_right) { // Adjust leftmost edge. if(vp->v_left < pp->v_left) rev_left = vp->v_left; else rev_left = pp->v_left; pp->v_left = vp->v_left; if(rev_left < update_column) { vir_left = vp->v_text + rev_left; phy_left = pp->v_text + rev_left; update_column = rev_left; } // Adjust rightmost edge. if(vp->v_right > pp->v_right) rev_right = vp->v_right; else rev_right = pp->v_right; pp->v_right = vp->v_right; if(vp->v_text + rev_right > vir_right) { vir_right = vp->v_text + rev_right; phy_right = pp->v_text + rev_right; } } else { rev_left = vp->v_left; rev_right = vp->v_right; } // If both lines are the same, no update needs to be done. if(!(pp->v_flags & VFNEW) && vir_left > vir_right) { vp->v_flags &= ~VFCHGD; // Clear changed flag. return rc.status; } left_blank = vir_right; // Erase to EOL? if(non_blanks == false && (opflags & OPHAVEEOL)) { while(left_blank != vir_left && left_blank[-1] == ' ') --left_blank; if(vir_right - left_blank <= 3) // Use only if erase is > 3 characters. left_blank = vir_right; } // Move to the beginning of the text to update. if(movecursor(row,update_column) != SUCCESS) return rc.status; while(vir_left != left_blank) { // Ordinary. // Are we in a reverse video field? if(pp->v_left <= update_column && update_column < pp->v_right) new_rev_state = true; else new_rev_state = false; // If moving in or out of reverse video, change it. if(new_rev_state != old_rev_state) { if(TTrev(new_rev_state) != SUCCESS) return rc.status; old_rev_state = new_rev_state; } // Output the next character. if(TTputc(*vir_left) != SUCCESS) return rc.status; ++update_column; *phy_left++ = *vir_left++; } if(left_blank != vir_right) { // Erase. // Are we in a reverse video field? if(pp->v_left <= update_column && update_column < pp->v_right) new_rev_state = true; else new_rev_state = false; // If moving in or out of reverse video, change it. if(new_rev_state != old_rev_state) { if(TTrev(new_rev_state) != SUCCESS) return rc.status; old_rev_state = new_rev_state; } #if TT_TERMCAP // TERMCAP does not tell us if the current terminal propagates the current attributes to the end of the line // when an erase to end of line sequence is sent. Don't let TERMCAP use EEOL if in a reverse video line! if(new_rev_state == true) while(update_column++ < (int) term.t_ncol) { if(TTputc(' ') != SUCCESS) return rc.status; } else if(TTeeol() != SUCCESS) return rc.status; #else if(TTeeol() != SUCCESS) return rc.status; #endif while(vir_left != vir_right) *phy_left++ = *vir_left++; } vp->v_flags &= ~VFCHGD; // Flag this line as updated. #if COLOR vp->v_flags &= ~VFCOLOR; #endif // Always leave in the default state. if(old_rev_state == true) (void) TTrev(false); return rc.status; }
/* * 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; }