/* * 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) { KEYTAB *ktp; int status; ktp = &keytab[0]; /* Look in key table */ while (ktp->k_fp != NULL) { if (ktp->k_code == c) { /* block if not suitable for a read only buffer */ if (ktp->k_flag == BFRO && (curwp->w_bufp->b_flag & BFRO) == BFRO) { return rdonly(); } else { thisflag = 0; status = (*ktp->k_fp) (f, n); lastflag = thisflag; return (status); } } ++ktp; } if ((c >= 0x20 && c <= 0x7E) /* Self inserting */ || (c >= 0xA0 && c <= 0xFE)) { /* can we self insert */ if (BFRO == (curwp->w_bufp->b_flag & BFRO)) return rdonly(); if (n <= 0) { /* Fenceposts */ lastflag = 0; return (n < 0 ? FALSE : TRUE); } thisflag = 0; /* For the future */ status = linsert (n, c); lastflag = thisflag; return (status); } mlwrite ("\007[Key not bound]"); /* complain */ lastflag = 0; /* Fake last flags */ return (FALSE); }
/* * Move the cursor forward by the specified number of words. As you move * convert characters to lower case. Error if you try and move over the end of * the buffer. Bound to "M-L". */ int lowerword(int f, int n) { register int c; CELL ac; ac.a = 0; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); while (n--) { while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); } while (inword() != FALSE) { c = lgetc(curwp->w_dotp, curwp->w_doto).c; if (c>='A' && c<='Z') { ac.c (c += 'a'-'A'); lputc(curwp->w_dotp, curwp->w_doto, ac); lchange(WFHARD); } if (forwchar(FALSE, 1) == FALSE) return (FALSE); } } return (TRUE); }
/* * Kill backwards by "n" words. Move backwards by the desired number of words, * counting the characters. When dot is finally moved to its resting place, * fire off the kill command. Bound to "M-Rubout" and to "M-Backspace". */ int delbword(int f, int n) { register long size; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); if (backchar(FALSE, 1) == FALSE) return (FALSE); size = 0L; while (n--) { while (inword() == FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } while (inword() != FALSE) { if (backchar(FALSE, 1) == FALSE) return (FALSE); ++size; } } if (forwchar(FALSE, 1) == FALSE) return (FALSE); return (ldelete(size, kinsert)); }
/* * Blast the region without saving . Ask "getregion" * to figure out the bounds of the region. * Move "." to the start, and kill the characters. * Bound to "C-W". */ int deleteregion(int f, int n) { REGION region; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (getregion(®ion, curwp->w_markp, curwp->w_marko) == TRUE){ curwp->w_dotp = region.r_linep; curwp->w_doto = region.r_offset; curwp->w_markp = NULL; #ifdef _WINDOWS mswin_allowcopycut(NULL); #endif if(ldelete(region.r_size, NULL)){ if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){ curwp->w_force = 0; /* Center dot. */ curwp->w_flag |= WFFORCE; } return(TRUE); } } return (FALSE); }
/* * Save the contents of the current * buffer in its associatd file. No nothing * if nothing has changed (this may be a bug, not a * feature). Error if there is no remembered file * name for the buffer. Bound to "C-X C-S". May * get called by "C-Z". */ int filesave(int f, int n) { struct window *wp; int s; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ if ((curbp->b_flag & BFCHG) == 0) /* Return, no changes. */ return TRUE; if (curbp->b_fname[0] == 0) { /* Must have a name. */ mlwrite("No file name"); return FALSE; } /* complain about truncated files */ if ((curbp->b_flag & BFTRUNC) != 0) { if (mlyesno("Truncated file ... write it out") == FALSE) { mlwrite("(Aborted)"); return FALSE; } } if ((s = writeout(curbp->b_fname)) == TRUE) { curbp->b_flag &= ~BFCHG; wp = wheadp; /* Update mode lines. */ while (wp != NULL) { if (wp->w_bufp == curbp) wp->w_flag |= WFMODE; wp = wp->w_wndp; } } return s; }
int check_editable(BUFFER *bp) { int status = TRUE; if (valid_buffer(bp) && b_val(bp, MDVIEW)) status = rdonly(); return status; }
/* ARGSUSED */ void acl3_setacl(SETACL3args *args, SETACL3res *resp, struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro) { int error; vnode_t *vp; vattr_t *vap; vattr_t va; vap = NULL; vp = nfs3_fhtovp(&args->fh, exi); if (vp == NULL) { error = ESTALE; goto out1; } (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); va.va_mask = AT_ALL; vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va; if (rdonly(ro, vp)) { resp->status = NFS3ERR_ROFS; goto out1; } error = VOP_SETSECATTR(vp, &args->acl, 0, cr, NULL); va.va_mask = AT_ALL; vap = rfs4_delegated_getattr(vp, &va, 0, cr) ? NULL : &va; if (error) goto out; VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); VN_RELE(vp); resp->status = NFS3_OK; vattr_to_post_op_attr(vap, &resp->resok.attr); return; out: if (curthread->t_flag & T_WOULDBLOCK) { curthread->t_flag &= ~T_WOULDBLOCK; resp->status = NFS3ERR_JUKEBOX; } else resp->status = puterrno3(error); out1: if (vp != NULL) { VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); VN_RELE(vp); } vattr_to_post_op_attr(vap, &resp->resfail.attr); }
/* * Insert a newline into the buffer at the current location of dot in the * current window. The funny ass-backwards way it does things is not a botch; * it just makes the last line in the file not a special case. Return TRUE if * everything works out and FALSE on error (memory allocation failure). The * update of dot and mark is a bit easier then in the above case, because the * split forces more updating. */ int lnewline(void) { char *cp1; char *cp2; struct line *lp1; struct line *lp2; int doto; struct window *wp; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ #if SCROLLCODE lchange(WFHARD | WFINS); #else lchange(WFHARD); #endif lp1 = curwp->w_dotp; /* Get the address and */ doto = curwp->w_doto; /* offset of "." */ if ((lp2 = lalloc(doto)) == NULL) /* New first half line */ return FALSE; cp1 = &lp1->l_text[0]; /* Shuffle text around */ cp2 = &lp2->l_text[0]; while (cp1 != &lp1->l_text[doto]) *cp2++ = *cp1++; cp2 = &lp1->l_text[0]; while (cp1 != &lp1->l_text[lp1->l_used]) *cp2++ = *cp1++; lp1->l_used -= doto; lp2->l_bp = lp1->l_bp; lp1->l_bp = lp2; lp2->l_bp->l_fp = lp2; lp2->l_fp = lp1; wp = wheadp; /* Windows */ while (wp != NULL) { if (wp->w_linep == lp1) wp->w_linep = lp2; if (wp->w_dotp == lp1) { if (wp->w_doto < doto) wp->w_dotp = lp2; else wp->w_doto -= doto; } if (wp->w_markp == lp1) { if (wp->w_marko < doto) wp->w_markp = lp2; else wp->w_marko -= doto; } wp = wp->w_wndp; } return TRUE; }
/* * Insert a file into the current * buffer. This is really easy; all you do it * find the name of the file, and call the standard * "insert a file into the current buffer" code. * Bound to "C-X C-I". */ insfile(f, n) { register int s; char fname[NFILEN]; if (restflag) /* don't allow this command if restricted */ return(resterr()); if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if ((s=mlreply("Insert file: ", fname, NFILEN)) != TRUE) return(s); return(ifile(fname)); }
PASCAL NEAR removefold( int f, int n ) { BUFFER *bp; /* buffer having fold removed */ WINDOW *wp; /* windows to fix up pointers in as well */ LINE *lp; /* line loop for reset of margin */ int margval; /* value to set margin to */ if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ /* find the proper buffer */ bp = curwp->w_bufp; if (curwp->w_dotp->l_type == LSOFOLD) { /* set line types to normal */ curwp->w_dotp->l_type = LNORMAL; curwp->w_dotp->l_foldp->l_type = LNORMAL; /* set all margins to that of any outer fold */ margval = minleftmarg(curwp->w_dotp); lp = curwp->w_dotp->l_fp; while (lp != curwp->w_dotp->l_foldp) { lp->l_lmargin = margval; lp = lforw(lp); } /* and remove them */ lfree(curwp->w_dotp->l_foldp); lfree(curwp->w_dotp); /* let all the proper windows be updated */ wp = wheadp; while (wp) { if (wp->w_bufp == bp) wp->w_flag |= (WFHARD|WFMODE); wp = wp->w_wndp; } bp->b_flag |= BFCHG; /* flag change */ mlwrite(TEXT233); /* "[Fold Removed]" */ return(TRUE); } else { mlwrite(TEXT235); /* "%% Not a fold line" */ return(FALSE); } }
/* * Insert a newline. Bound to "C-M". */ int newline(int f, int n) { register int s; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); if(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l)){ if(curwp->w_doto != 0) l++; scrolldown(curwp, l, n); } } /* if we are in C mode and this is a default <NL> */ /* pico's never in C mode */ if(Pmaster && Pmaster->allow_flowed_text && curwp->w_doto && ucs4_isspace(lgetc(curwp->w_dotp, curwp->w_doto - 1).c) && !(curwp->w_doto == 3 && lgetc(curwp->w_dotp, 0).c == '-' && lgetc(curwp->w_dotp, 1).c == '-' && lgetc(curwp->w_dotp, 2).c == ' ')){ /* * flowed mode, make the newline a hard one by * stripping trailing space. */ int i, dellen; for(i = curwp->w_doto - 1; i && ucs4_isspace(lgetc(curwp->w_dotp, i - 1).c); i--); dellen = curwp->w_doto - i; curwp->w_doto = i; ldelete(dellen, NULL); } /* insert some lines */ while (n--) { if ((s=lnewline()) != TRUE) return (s); } return (TRUE); }
/* * Insert a file into the current * buffer. This is really easy; all you do it * find the name of the file, and call the standard * "insert a file into the current buffer" code. * Bound to "C-X C-I". */ int insfile(int f, int n) { int s; char fname[NFILEN]; if (restflag) /* don't allow this command if restricted */ return resterr(); if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ if ((s = mlreply("Insert file: ", fname, NFILEN)) != TRUE) return s; if ((s = ifile(fname)) != TRUE) return s; return reposition(TRUE, -1); }
/* ARGSUSED */ void acl2_setacl(SETACL2args *args, SETACL2res *resp, struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro) { int error; vnode_t *vp; vattr_t va; vp = nfs_fhtovp(&args->fh, exi); if (vp == NULL) { resp->status = NFSERR_STALE; return; } if (rdonly(ro, vp)) { VN_RELE(vp); resp->status = NFSERR_ROFS; return; } (void) VOP_RWLOCK(vp, V_WRITELOCK_TRUE, NULL); error = VOP_SETSECATTR(vp, &args->acl, 0, cr, NULL); if (error) { VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); VN_RELE(vp); resp->status = puterrno(error); return; } va.va_mask = AT_ALL; error = rfs4_delegated_getattr(vp, &va, 0, cr); VOP_RWUNLOCK(vp, V_WRITELOCK_TRUE, NULL); VN_RELE(vp); /* check for overflowed values */ if (!error) { error = vattr_to_nattr(&va, &resp->resok.attr); } if (error) { resp->status = puterrno(error); return; } resp->status = NFS_OK; }
/* * Kill forward by "n" words. Remember the location of dot. Move forward by * the right number of words. Put dot back where it was and issue the kill * command for the right number of characters. Bound to "M-D". */ int delfword(int f, int n) { register long size; register LINE *dotp; register int doto; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (FALSE); dotp = curwp->w_dotp; doto = curwp->w_doto; size = 0L; while (n--) { #if NFWORD while (inword() != FALSE) { if (forwchar(FALSE,1) == FALSE) return(FALSE); ++size; } #endif while (inword() == FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); ++size; } #if NFWORD == 0 while (inword() != FALSE) { if (forwchar(FALSE, 1) == FALSE) return (FALSE); ++size; } #endif } curwp->w_dotp = dotp; curwp->w_doto = doto; return (ldelete(size, kinsert)); }
/* * Insert "n" copies of the character "c" at the current location of dot. In * the easy case all that happens is the text is stored in the line. In the * hard case, the line has to be reallocated. When the window list is updated, * take special care; I screwed it up once. You always update dot in the * current window. You update mark, and a dot in another window, if it is * greater than the place where you did the insert. Return TRUE if all is * well, and FALSE on errors. */ int linsert(int n, UCS c) { register LINE *dotp; register int doto; register WINDOW *wp; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ dotp = curwp->w_dotp; doto = curwp->w_doto; lchange(WFEDIT); if(!geninsert(&(curwp->w_dotp), &(curwp->w_doto), curbp->b_linep, c, (curwp->w_markp) ? 1 : 0, n, &curbp->b_linecnt)) return(FALSE); wp = wheadp; /* Update windows */ while (wp != NULL) { if (wp->w_linep == dotp) wp->w_linep = wp->w_dotp; if (wp->w_imarkp == dotp) { /* added for internal mark */ wp->w_imarkp = wp->w_dotp; if (wp->w_imarko > doto) wp->w_imarko += n; } if (wp->w_markp == dotp) { wp->w_markp = dotp; if (wp->w_marko > doto) wp->w_marko += n; } wp = wp->w_wndp; } return (TRUE); }
/* * Yank text back from the kill buffer. This is really easy. All of the work * is done by the standard insert routines. All you do is run the loop, and * check for errors. Bound to "C-Y". */ int yank(int f, int n) { int c; int i; char *sp; /* pointer into string to insert */ struct kill *kp; /* pointer into kill buffer */ if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ if (n < 0) return FALSE; /* make sure there is something to yank */ if (kbufh == NULL) return TRUE; /* not an error, just nothing */ /* for each time.... */ while (n--) { kp = kbufh; while (kp != NULL) { if (kp->d_next == NULL) i = kused; else i = KBLOCK; sp = kp->d_chunk; while (i--) { if ((c = *sp++) == '\n') { if (lnewline() == FALSE) return FALSE; } else { if (linsert(1, c) == FALSE) return FALSE; } } kp = kp->d_next; } } return TRUE; }
/* * Delete backwards. This is quite easy too, because it's all done with other * functions. Just move the cursor back, and delete forwards. Like delete * forward, this actually does a kill if presented with an argument. Bound to * both "RUBOUT" and "C-H". */ int backdel(int f, int n) { register int s; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (forwdel(f, -n)); if(TERM_OPTIMIZE && curwp->w_dotp != curwp->w_bufp->b_linep){ int l; if(worthit(&l) && curwp->w_doto == 0 && lback(curwp->w_dotp) != curwp->w_bufp->b_linep){ if(l == curwp->w_toprow) scrollup(curwp, l+1, 1); else if(llength(lback(curwp->w_dotp)) == 0) scrollup(curwp, l-1, 1); else scrollup(curwp, l, 1); } } if (f != FALSE) { /* Really a kill. */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; } if ((s=backchar(f, n)) == TRUE) s = ldelete((long) n, f ? kinsert : NULL); return (s); }
/* * killtext - delete the line that the cursor is currently in. * a greatly pared down version of its former self. */ int killtext(int f, int n) { register int chunk; int opt_scroll = 0; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if ((lastflag&CFKILL) == 0) /* Clear kill buffer if */ kdelete(); /* last wasn't a kill. */ if(gmode & MDDTKILL){ /* */ if((chunk = llength(curwp->w_dotp) - curwp->w_doto) == 0){ chunk = 1; if(TERM_OPTIMIZE) opt_scroll = 1; } } else{ gotobol(FALSE, 1); /* wack from bol past newline */ chunk = llength(curwp->w_dotp) + 1; if(TERM_OPTIMIZE) opt_scroll = 1; } /* optimize what motion we can */ if(opt_scroll && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l)) scrollup(curwp, l, 1); } thisflag |= CFKILL; return(ldelete((long) chunk, kinsert)); }
/* * Delete forward. This is real easy, because the basic delete routine does * all of the work. Watches for negative arguments, and does the right thing. * If any argument is present, it kills rather than deletes, to prevent loss * of text if typed with a big argument. Normally bound to "C-D". */ int forwdel(int f, int n) { if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (n < 0) return (backdel(f, -n)); if(TERM_OPTIMIZE && (curwp->w_dotp != curwp->w_bufp->b_linep)){ int l; if(worthit(&l) && curwp->w_doto == llength(curwp->w_dotp)) scrollup(curwp, l+1, 1); } if (f != FALSE) { /* Really a kill. */ if ((lastflag&CFKILL) == 0) kdelete(); thisflag |= CFKILL; } return (ldelete((long) n, f ? kinsert : NULL)); }
/* * Kill the region. Ask "getregion" * to figure out the bounds of the region. * Move "." to the start, and kill the characters. * Bound to "C-W". */ int killregion(int f, int n) { REGION region; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if (getregion(®ion, curwp->w_markp, curwp->w_marko) != TRUE){ return (killtext(f, n)); }else { mlerase(); } if ((lastflag&CFKILL) == 0) /* This is a kill type */ kdelete(); /* command, so do magic */ thisflag |= CFKILL; /* kill buffer stuff. */ curwp->w_dotp = region.r_linep; curwp->w_doto = region.r_offset; curwp->w_markp = NULL; #ifdef _WINDOWS mswin_allowcopycut(NULL); #endif if(ldelete(region.r_size, kinsert)){ if(curwp->w_dotp == curwp->w_linep && curwp->w_dotp == curbp->b_linep){ curwp->w_force = 0; /* Center dot. */ curwp->w_flag |= WFFORCE; } return(TRUE); } return (FALSE); }
/* * Upper case region. Zap all of the lower * case characters in the region to upper case. Use * the region code to set the limits. Scan the buffer, * doing the changes. Call "lchange" to ensure that * redisplay is done in all buffers. Bound to * "C-X C-L". */ int upperregion(int f, int n) { register LINE *linep; register int loffs; register int c; register int s; REGION region; CELL ac; ac.a = 0; if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if ((s=getregion(®ion, curwp->w_markp, curwp->w_marko)) != TRUE) return (s); lchange(WFHARD); linep = region.r_linep; loffs = region.r_offset; while (region.r_size--) { if (loffs == llength(linep)) { linep = lforw(linep); loffs = 0; } else { c = lgetc(linep, loffs).c; if (c>='a' && c<='z'){ ac.c = c - 'a' + 'A'; lputc(linep, loffs, ac); } ++loffs; } } return (TRUE); }
PASCAL NEAR makefold(f, n) { register int status; /* return status */ BUFFER *bp; /* buffer being folded*/ WINDOW *wp; /* windows to fix up pointers in as well */ REGION creg; /* region boundry structure */ char foldstr[NSTRING]; /* Fold string to insert into buffer/file */ LINE *topboundary; /* Line before fold */ LINE *botboundary; /* Line after fold */ int i; /* Loop */ char mprefix[NSTRING]; /* mark prefix */ int lm; /* left margin value */ LINE *lp; /* line pointer */ short ltype; /* saved line type */ if (curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ /* find the proper buffer */ bp = curwp->w_bufp; /* find the boundries of the current region */ /* remember these could be fold lines */ /* call getrawregion first, cos this will check if we cross crease */ if ((status=getrawregion(&creg)) != TRUE) return(status); /* check if we have to indent the fold marker */ i = 0; lm = curwp->w_markp[0]->l_lmargin; if (curwp->w_marko[0] > lm) { while (((curwp->w_markp[0]->l_text[i + lm] == ' ') || (curwp->w_markp[0]->l_text[i + lm] == '\t')) && (i + lm < curwp->w_marko[0])) { mprefix[i] = curwp->w_markp[0]->l_text[i + lm]; i++; } } mprefix[i] = NULL; if ((status=getregion(&creg)) != TRUE) return(status); curwp->w_dotp = creg.r_linep; /* only by full lines */ curwp->w_doto = 0; creg.r_size += (long)creg.r_offset; if (creg.r_size <= (long)curwp->w_dotp->l_used) { mlwrite(TEXT222); /* "%%Must fold at least 1 full line" */ return(FALSE); } /* insert the mapped fold-start line at top */ /* have to insert and backup since it could already be a fold line */ /* Unless line is normal cannot insert nl at left margin */ ltype = curwp->w_dotp->l_type; curwp->w_dotp->l_type = LNORMAL; curwp->w_doto = curwp->w_dotp->l_lmargin; lnewline(); /* Reset line type, backup and insert fold symbol */ curwp->w_dotp->l_type = ltype; curwp->w_dotp = curwp->w_dotp->l_bp; strcpy(foldstr, mprefix); strcat(foldstr, FOLDSYMBOL); linstr(foldstr); topboundary = curwp->w_dotp; curwp->w_dotp = curwp->w_dotp->l_fp; curwp->w_doto = 0; /* move forward to the end of this region (a long number of bytes perhaps) */ while (creg.r_size > (long)32000) { forwchar(TRUE, 32000); creg.r_size -= (long)32000; } forwchar(TRUE, (int)creg.r_size); curwp->w_doto = 0; /* only full lines! */ /* Unless line is normal cannot insert nl at left margin */ ltype = curwp->w_dotp->l_type; /* exception is end of open fold */ if (ltype == LEOEFOLD) curwp->w_doto = loffset(curwp->w_dotp); else { curwp->w_dotp->l_type = LNORMAL; curwp->w_doto = curwp->w_dotp->l_lmargin; } lnewline(); /* Reset line type, backup and insert end fold symbol */ curwp->w_dotp->l_type = ltype; curwp->w_dotp = curwp->w_dotp->l_bp; strcpy(foldstr, mprefix); strcat(foldstr, ENDFOLD); linstr(foldstr); botboundary = curwp->w_dotp; /* set the fold pointers and line types */ topboundary->l_type = LSOFOLD; topboundary->l_foldp = botboundary; botboundary->l_type = LEOFOLD; botboundary->l_foldp = topboundary; /* set left margin? */ if (i) { curwp->w_dotp = topboundary->l_fp; i += curwp->w_dotp->l_lmargin; while (curwp->w_dotp != botboundary) { if (loffset(curwp->w_dotp) < i) { /* insert prefix - else problems! */ curwp->w_doto = curwp->w_dotp->l_lmargin; linstr(mprefix); } if (curwp->w_dotp->l_lmargin < i) /* not inner fold */ curwp->w_dotp->l_lmargin = i; curwp->w_dotp = curwp->w_dotp->l_fp; /* lforw() won't find the line */ } } /* move cursor to fold line */ curwp->w_dotp = topboundary; curwp->w_doto = llength(curwp->w_dotp); /* clear out marks */ for (i = 0; i < NMARKS; i++) bp->b_markp[i] = (LINE *)NULL; /* let all the proper windows be updated */ wp = wheadp; while (wp) { if (wp->w_bufp == bp) wp->w_flag |= (WFHARD|WFMODE); wp = wp->w_wndp; } mlwrite(TEXT224); /* "[Buffer folded]" */ return(TRUE); }
/* ARGSUSED */ void acl2_access(ACCESS2args *args, ACCESS2res *resp, struct exportinfo *exi, struct svc_req *req, cred_t *cr, bool_t ro) { int error; vnode_t *vp; vattr_t va; int checkwriteperm; vp = nfs_fhtovp(&args->fh, exi); if (vp == NULL) { resp->status = NFSERR_STALE; return; } /* * If the file system is exported read only, it is not appropriate * to check write permissions for regular files and directories. * Special files are interpreted by the client, so the underlying * permissions are sent back to the client for interpretation. */ if (rdonly(ro, vp) && (vp->v_type == VREG || vp->v_type == VDIR)) checkwriteperm = 0; else checkwriteperm = 1; /* * We need the mode so that we can correctly determine access * permissions relative to a mandatory lock file. Access to * mandatory lock files is denied on the server, so it might * as well be reflected to the server during the open. */ va.va_mask = AT_MODE; error = VOP_GETATTR(vp, &va, 0, cr, NULL); if (error) { VN_RELE(vp); resp->status = puterrno(error); return; } resp->resok.access = 0; if (args->access & ACCESS2_READ) { error = VOP_ACCESS(vp, VREAD, 0, cr, NULL); if (!error && !MANDLOCK(vp, va.va_mode)) resp->resok.access |= ACCESS2_READ; } if ((args->access & ACCESS2_LOOKUP) && vp->v_type == VDIR) { error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL); if (!error) resp->resok.access |= ACCESS2_LOOKUP; } if (checkwriteperm && (args->access & (ACCESS2_MODIFY|ACCESS2_EXTEND))) { error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL); if (!error && !MANDLOCK(vp, va.va_mode)) resp->resok.access |= (args->access & (ACCESS2_MODIFY|ACCESS2_EXTEND)); } if (checkwriteperm && (args->access & ACCESS2_DELETE) && (vp->v_type == VDIR)) { error = VOP_ACCESS(vp, VWRITE, 0, cr, NULL); if (!error) resp->resok.access |= ACCESS2_DELETE; } if (args->access & ACCESS2_EXECUTE) { error = VOP_ACCESS(vp, VEXEC, 0, cr, NULL); if (!error && !MANDLOCK(vp, va.va_mode)) resp->resok.access |= ACCESS2_EXECUTE; } va.va_mask = AT_ALL; error = rfs4_delegated_getattr(vp, &va, 0, cr); VN_RELE(vp); /* check for overflowed values */ if (!error) { error = vattr_to_nattr(&va, &resp->resok.attr); } if (error) { resp->status = puterrno(error); return; } resp->status = NFS_OK; }
/* Justify the entire buffer instead of just a paragraph */ int fillbuf(int f, int n) { LINE *eobline; REGION region; if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ } else if (fillcol == 0) { /* no fill column set */ mlwrite_utf8("No fill column set", NULL); return(FALSE); } if((lastflag & CFFILL) && (lastflag & CFFLBF)){ /* no use doing a full justify twice */ thisflag |= (CFFLBF | CFFILL); return(TRUE); } /* record the pointer of the last line */ if(gotoeob(FALSE, 1) == FALSE) return(FALSE); eobline = curwp->w_dotp; /* last line of buffer */ if(!llength(eobline)) eobline = lback(eobline); /* and back to the beginning of the buffer */ gotobob(FALSE, 1); thisflag |= CFFLBF; /* CFFILL also gets set in fillpara */ if(!Pmaster) sgarbk = TRUE; curwp->w_flag |= WFMODE; /* * clear the kill buffer, that's where we'll store undo * information, we can't do the fill buffer because * fillpara relies on its contents */ kdelete(); curwp->w_doto = 0; getregion(®ion, eobline, llength(eobline)); /* Put full message in the kill buffer for undo */ if(!ldelete(region.r_size, kinsert)) return(FALSE); /* before yank'ing, clear lastflag so we don't just unjustify */ lastflag &= ~(CFFLBF | CFFILL); /* Now in kill buffer, bring back text to use in fillpara */ yank(FALSE, 1); gotobob(FALSE, 1); /* call fillpara until we're at the end of the buffer */ while(curwp->w_dotp != curbp->b_linep) if(!(fillpara(FALSE, 1))) return(FALSE); return(TRUE); }
/* * Delete a newline. Join the current line with the next line. If the next line * is the magic header line always return TRUE; merging the last line with the * header line can be thought of as always being a successful operation, even * if nothing is done, and this makes the kill buffer work "right". Easy cases * can be done by shuffling data around. Hard cases require that lines be moved * about in memory. Return FALSE on error and TRUE if all looks ok. Called by * "ldelete" only. */ int ldelnewline(void) { char *cp1; char *cp2; struct line *lp1; struct line *lp2; struct line *lp3; struct window *wp; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ lp1 = curwp->w_dotp; lp2 = lp1->l_fp; if (lp2 == curbp->b_linep) { /* At the buffer end. */ if (lp1->l_used == 0) /* Blank line. */ lfree(lp1); return TRUE; } if (lp2->l_used <= lp1->l_size - lp1->l_used) { cp1 = &lp1->l_text[lp1->l_used]; cp2 = &lp2->l_text[0]; while (cp2 != &lp2->l_text[lp2->l_used]) *cp1++ = *cp2++; wp = wheadp; while (wp != NULL) { if (wp->w_linep == lp2) wp->w_linep = lp1; if (wp->w_dotp == lp2) { wp->w_dotp = lp1; wp->w_doto += lp1->l_used; } if (wp->w_markp == lp2) { wp->w_markp = lp1; wp->w_marko += lp1->l_used; } wp = wp->w_wndp; } lp1->l_used += lp2->l_used; lp1->l_fp = lp2->l_fp; lp2->l_fp->l_bp = lp1; free((char *) lp2); return TRUE; } if ((lp3 = lalloc(lp1->l_used + lp2->l_used)) == NULL) return FALSE; cp1 = &lp1->l_text[0]; cp2 = &lp3->l_text[0]; while (cp1 != &lp1->l_text[lp1->l_used]) *cp2++ = *cp1++; cp1 = &lp2->l_text[0]; while (cp1 != &lp2->l_text[lp2->l_used]) *cp2++ = *cp1++; lp1->l_bp->l_fp = lp3; lp3->l_fp = lp2->l_fp; lp2->l_fp->l_bp = lp3; lp3->l_bp = lp1->l_bp; wp = wheadp; while (wp != NULL) { if (wp->w_linep == lp1 || wp->w_linep == lp2) wp->w_linep = lp3; if (wp->w_dotp == lp1) wp->w_dotp = lp3; else if (wp->w_dotp == lp2) { wp->w_dotp = lp3; wp->w_doto += lp1->l_used; } if (wp->w_markp == lp1) wp->w_markp = lp3; else if (wp->w_markp == lp2) { wp->w_markp = lp3; wp->w_marko += lp1->l_used; } wp = wp->w_wndp; } free((char *) lp1); free((char *) lp2); return TRUE; }
/* * This function deletes "n" bytes, starting at dot. It understands how do deal * with end of lines, etc. It returns TRUE if all of the characters were * deleted, and FALSE if they were not (because dot ran into the end of the * buffer. The "kflag" is TRUE if the text should be put in the kill buffer. * * long n; # of chars to delete * int kflag; put killed text in kill buffer flag */ int ldelete(long n, int kflag) { char *cp1; char *cp2; struct line *dotp; int doto; int chunk; struct window *wp; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ while (n != 0) { dotp = curwp->w_dotp; doto = curwp->w_doto; if (dotp == curbp->b_linep) /* Hit end of buffer. */ return FALSE; chunk = dotp->l_used - doto; /* Size of chunk. */ if (chunk > n) chunk = n; if (chunk == 0) { /* End of line, merge. */ #if SCROLLCODE lchange(WFHARD | WFKILLS); #else lchange(WFHARD); #endif if (ldelnewline() == FALSE || (kflag != FALSE && kinsert('\n') == FALSE)) return FALSE; --n; continue; } lchange(WFEDIT); cp1 = &dotp->l_text[doto]; /* Scrunch text. */ cp2 = cp1 + chunk; if (kflag != FALSE) { /* Kill? */ while (cp1 != cp2) { if (kinsert(*cp1) == FALSE) return FALSE; ++cp1; } cp1 = &dotp->l_text[doto]; } while (cp2 != &dotp->l_text[dotp->l_used]) *cp1++ = *cp2++; dotp->l_used -= chunk; wp = wheadp; /* Fix windows */ while (wp != NULL) { if (wp->w_dotp == dotp && wp->w_doto >= doto) { wp->w_doto -= chunk; if (wp->w_doto < doto) wp->w_doto = doto; } if (wp->w_markp == dotp && wp->w_marko >= doto) { wp->w_marko -= chunk; if (wp->w_marko < doto) wp->w_marko = doto; } wp = wp->w_wndp; } n -= chunk; } return TRUE; }
/* * Fill the current paragraph according to the current fill column */ int fillpara(int f, int n) { UCS *qstr, qstr2[NSTRING], c; int quotelevel = -1; REGION addedregion; char action = 'P'; if(curbp->b_mode&MDVIEW){ /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ } else if (fillcol == 0) { /* no fill column set */ mlwrite_utf8("No fill column set", NULL); return(FALSE); } else if(curwp->w_dotp == curbp->b_linep && !curwp->w_markp) /* don't wrap! */ return(FALSE); /* * If there is already a region set, then we may use it * instead of the current paragraph. */ if(curwp->w_markp){ int k, rv; KEYMENU menu_justify[12]; char prompt[100]; for(k = 0; k < 12; k++){ menu_justify[k].name = NULL; KS_OSDATASET(&menu_justify[k], KS_NONE); } menu_justify[1].name = "R"; menu_justify[1].label = "[" N_("Region") "]"; menu_justify[6].name = "^C"; menu_justify[6].label = N_("Cancel"); menu_justify[7].name = "P"; menu_justify[7].label = N_("Paragraph"); menu_justify[2].name = "Q"; menu_justify[2].label = N_("Quotelevel"); wkeyhelp(menu_justify); /* paint menu */ sgarbk = TRUE; if(Pmaster && curwp) curwp->w_flag |= WFMODE; strncpy(prompt, "justify Region, Paragraph; or fix Quotelevel ? ", sizeof(prompt)); prompt[sizeof(prompt)-1] = '\0'; mlwrite_utf8(prompt, NULL); (*term.t_rev)(1); rv = -1; while(1){ switch(c = GetKey()){ case (CTRL|'C') : /* Bail out! */ case F2 : pputs_utf8(_("ABORT"), 1); rv = ABORT; emlwrite("", NULL); break; case (CTRL|'M') : /* default */ case 'r' : case 'R' : case F3 : pputs_utf8(_("Region"), 1); rv = 'R'; break; case 'p' : case 'P' : case F7 : pputs_utf8(_("Paragraph"), 1); rv = 'P'; break; case 'q' : case 'Q' : case F8 : case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : pputs_utf8(_("Quotelevel"), 1); while(rv == -1){ switch(c){ case 'q' : case 'Q' : case F8 : {char num[20]; num[0] = '\0'; switch(mlreplyd_utf8("Quote Level ? ", num, sizeof(num), QNORML, NULL)){ case TRUE: if(isdigit(num[0])){ quotelevel = atoi(num); if(quotelevel < 0){ emlwrite("Quote Level cannot be negative", NULL); sleep(3); } else if(quotelevel > 20){ emlwrite("Quote Level should be less than 20", NULL); rv = ABORT; } else{ rv = 'Q'; } } else if(num[0]){ emlwrite("Quote Level should be a number", NULL); sleep(3); } break; case HELPCH: emlwrite("Enter the number of quotes you want before the text", NULL); sleep(3); break; default: emlwrite("Quote Level is a number", NULL); rv = ABORT; break; } } break; case '0' : case '1' : case '2' : case '3' : case '4' : case '5' : case '6' : case '7' : case '8' : case '9' : rv = 'Q'; quotelevel = (int) (c - '0'); break; } } break; case (CTRL|'G') : if(term.t_mrow == 0 && km_popped == 0){ movecursor(term.t_nrow-2, 0); peeol(); term.t_mrow = 2; (*term.t_rev)(0); wkeyhelp(menu_justify); mlwrite_utf8(prompt, NULL); (*term.t_rev)(1); sgarbk = TRUE; /* mark menu dirty */ km_popped++; break; } /* else fall through */ default: (*term.t_beep)(); case NODATA : break; } (*term.t_flush)(); if(rv != -1){ (*term.t_rev)(0); if(km_popped){ term.t_mrow = 0; movecursor(term.t_nrow, 0); peeol(); sgarbf = 1; km_popped = 0; } action = rv; break; } } if(action != ABORT) emlwrite("", NULL); } if(action == 'R' && curwp->w_markp){ /* let yank() know that it may be restoring a paragraph */ thisflag |= CFFILL; if(!Pmaster) sgarbk = TRUE; curwp->w_flag |= WFMODE; swap_mark_and_dot_if_mark_comes_first(); /* determine if we're justifying quoted text or not */ qstr = (glo_quote_str && quote_match(glo_quote_str, curwp->w_doto > 0 ? curwp->w_dotp->l_fp : curwp->w_dotp, qstr2, NSTRING) && *qstr2) ? qstr2 : NULL; /* * Fillregion moves dot to the end of the filled region. */ if(!fillregion(qstr, &addedregion)) return(FALSE); set_last_region_added(&addedregion); } else if(action == 'P'){ /* * Justfiy the current paragraph. */ if(curwp->w_markp) /* clear mark if already set */ setmark(0,0); if(gotoeop(FALSE, 1) == FALSE) return(FALSE); /* determine if we're justifying quoted text or not */ qstr = (glo_quote_str && quote_match(glo_quote_str, curwp->w_dotp, qstr2, NSTRING) && *qstr2) ? qstr2 : NULL; setmark(0,0); /* mark last line of para */ /* jump back to the beginning of the paragraph */ gotobop(FALSE, 1); /* let yank() know that it may be restoring a paragraph */ thisflag |= (CFFILL | CFFLPA); if(!Pmaster) sgarbk = TRUE; curwp->w_flag |= WFMODE; curwp->w_doto = 0; /* start region at beginning of line */ /* * Fillregion moves dot to the end of the filled region. */ if(!fillregion(qstr, &addedregion)) return(FALSE); set_last_region_added(&addedregion); /* Leave cursor on first char of first line after justified region */ curwp->w_dotp = lforw(curwp->w_dotp); curwp->w_doto = 0; if(curwp->w_markp) setmark(0,0); /* clear mark */ } else if(action == 'Q'){ /* let yank() know that it may be restoring a paragraph */ thisflag |= CFFILL; if(!Pmaster) sgarbk = TRUE; curwp->w_flag |= WFHARD; swap_mark_and_dot_if_mark_comes_first(); if(!setquotelevelinregion(quotelevel, &addedregion)) return(FALSE); set_last_region_added(&addedregion); } else{ /* abort */ } return(TRUE); }
int linsert(int n, int c) { char *cp1; char *cp2; struct line *lp1; struct line *lp2; struct line *lp3; int doto; int i; struct window *wp; if (curbp->b_mode & MDVIEW) /* don't allow this command if */ return rdonly(); /* we are in read only mode */ lchange(WFEDIT); lp1 = curwp->w_dotp; /* Current line */ if (lp1 == curbp->b_linep) { /* At the end: special */ if (curwp->w_doto != 0) { mlwrite("bug: linsert"); return FALSE; } if ((lp2 = lalloc(n)) == NULL) /* Allocate new line */ return FALSE; lp3 = lp1->l_bp; /* Previous line */ lp3->l_fp = lp2; /* Link in */ lp2->l_fp = lp1; lp1->l_bp = lp2; lp2->l_bp = lp3; for (i = 0; i < n; ++i) lp2->l_text[i] = c; curwp->w_dotp = lp2; curwp->w_doto = n; return TRUE; } doto = curwp->w_doto; /* Save for later. */ if (lp1->l_used + n > lp1->l_size) { /* Hard: reallocate */ if ((lp2 = lalloc(lp1->l_used + n)) == NULL) return FALSE; cp1 = &lp1->l_text[0]; cp2 = &lp2->l_text[0]; while (cp1 != &lp1->l_text[doto]) *cp2++ = *cp1++; cp2 += n; while (cp1 != &lp1->l_text[lp1->l_used]) *cp2++ = *cp1++; lp1->l_bp->l_fp = lp2; lp2->l_fp = lp1->l_fp; lp1->l_fp->l_bp = lp2; lp2->l_bp = lp1->l_bp; free((char *) lp1); } else { /* Easy: in place */ lp2 = lp1; /* Pretend new line */ lp2->l_used += n; cp2 = &lp1->l_text[lp1->l_used]; cp1 = cp2 - n; while (cp1 != &lp1->l_text[doto]) *--cp2 = *--cp1; } for (i = 0; i < n; ++i) /* Add the characters */ lp2->l_text[doto + i] = c; wp = wheadp; /* Update windows */ while (wp != NULL) { if (wp->w_linep == lp1) wp->w_linep = lp2; if (wp->w_dotp == lp1) { wp->w_dotp = lp2; if (wp == curwp || wp->w_doto > doto) wp->w_doto += n; } if (wp->w_markp == lp1) { wp->w_markp = lp2; if (wp->w_marko > doto) wp->w_marko += n; } wp = wp->w_wndp; } 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); }
int setquotelevelinregion(int quotelevel, REGION *addedregion) { int i, standards_based = 0; int quote_chars = 0, backuptoprevline = 0; int starts_midline = 0, ends_midline = 0, offset_into_start; long c, sz; UCS qstr_def1[] = { '>', ' ', 0}, qstr_def2[] = { '>', 0}; LINE *lp, *line_before_start; REGION region; if(curbp->b_mode&MDVIEW) /* don't allow this command if */ return(rdonly()); /* we are in read only mode */ if(!glo_quote_str || !ucs4_strcmp(glo_quote_str, qstr_def1) || !ucs4_strcmp(glo_quote_str, qstr_def2)) standards_based++; if(!standards_based){ emlwrite("Quote level setting only works with standard \"> \" quotes", NULL); return(FALSE); } /* if region starts midline insert a newline */ if(curwp->w_doto > 0 && curwp->w_doto < llength(curwp->w_dotp)) starts_midline++; /* if region ends midline insert a newline at end */ if(curwp->w_marko > 0 && curwp->w_marko < llength(curwp->w_markp)){ ends_midline++; backuptoprevline++; /* count quote chars for re-insertion */ for(i = 0; i < llength(curwp->w_markp); ++i) if(lgetc(curwp->w_markp, i).c != '>') break; quote_chars = i; } else if(curwp->w_marko == 0) backuptoprevline++; /* find the size of the region */ getregion(®ion, curwp->w_markp, curwp->w_marko); /* cut the paragraph into our fill buffer */ fdelete(); if(!ldelete(region.r_size, finsert)) return(FALSE); line_before_start = lback(curwp->w_dotp); offset_into_start = curwp->w_doto; /* if region starts midline add a newline */ if(starts_midline) lnewline(); i = 0; while(fremove(i) >= 0){ /* remove all quote strs from current line */ if(standards_based){ while((c = fremove(i)) == '>') i++; if(c == ' ') i++; } else{ } /* insert quotelevel quote strs */ if(standards_based){ linsert(quotelevel, '>'); if(quotelevel > 0) linsert(1, ' '); } else{ } /* put back the actual line */ while((c = fremove(i++)) >= 0 && c != '\n') linsert(1, (UCS) c); if(c == '\n') lnewline(); } /* if region ends midline add a newline */ if(ends_midline){ lnewline(); if(quote_chars){ linsert(quote_chars, '>'); if(curwp->w_doto < llength(curwp->w_dotp) && lgetc(curwp->w_dotp, curwp->w_doto).c != ' ') linsert(1, ' '); } } /* * Calculate the size of the region that was added. */ swapmark(0,1); /* mark current location after adds */ addedregion->r_linep = lforw(line_before_start); addedregion->r_offset = offset_into_start; lp = addedregion->r_linep; sz = llength(lp) - addedregion->r_offset; if(lforw(lp) != curwp->w_markp->l_fp){ lp = lforw(lp); while(lp != curwp->w_markp->l_fp){ sz += llength(lp) + 1; lp = lforw(lp); } } sz -= llength(curwp->w_markp) - curwp->w_marko; addedregion->r_size = sz; swapmark(0,1); /* * This puts us at the end of the quoted region instead * of on the following line. This makes it convenient * for the user to follow a quotelevel adjustment with * a Justify if desired. */ if(backuptoprevline){ curwp->w_doto = 0; backchar(0, 1); } if(ends_midline){ /* doesn't need fixing otherwise */ unmarkbuffer(); markregion(1); } return (TRUE); }