static void /* convert columns to power series */ cols(projUV **c, projUV **d, int nu, int nv) { projUV *sv, **dd; int j, k; dd = (projUV **)vector2(nu, nv, sizeof(projUV)); sv = (projUV *)vector1(nv, sizeof(projUV)); bclear(d, nu, nv); bclear(dd, nu, nv); bmove(d[0], c[nu-1], nv); for (j = nu-2; j >= 1; --j) { for (k = nu-j; k >= 1; --k) { bmove(sv, d[k], nv); submop(d[k], 2., d[k-1], dd[k], nv); bmove(dd[k], sv, nv); } bmove(sv, d[0], nv); subop(d[0], c[j], dd[0], nv); bmove(dd[0], sv, nv); } for (j = nu-1; j >= 1; --j) subop(d[j], d[j-1], dd[j], nv); submop(d[0], .5, c[0], dd[0], nv); freev2((void **) dd, nu); pj_dalloc(sv); }
/* Initialize for GD-ROM */ static int init_percd_gdrom() { int i; CDROM_TOC toc; /* Start off with no cached blocks */ bclear(); /* Locate the root session */ if ((i = cdrom_reinit()) != 0) return i; if ((i = cdrom_read_toc(&toc, 1)) != 0) return i; if (!(session_base = cdrom_locate_data_track(&toc, 1))) return -1; /* Grab and check the volume descriptor */ i = bread(session_base + 16 - 150); if (i < 0) return i; if (memcmp((char*)cache[i]->data, "\01CD001", 6)) { printf("fs_iso9660: disc is not iso9660\r\n"); return -1; } /* Locate the root directory */ memcpy(&root_dirent, cache[i]->data+156, sizeof(iso_dirent_t)); root_extent = iso_733(root_dirent.extent); root_size = iso_733(root_dirent.size); return 0; }
int shellcmdoutput(char* const argv[], char* const text, int len) { struct buffer *bp; char *shellp; int ret; bp = bfind("*Shell Command Output*", TRUE); bp->b_flag |= BFREADONLY; if (bclear(bp) != TRUE) { free(text); return (FALSE); } shellp = getenv("SHELL"); ret = pipeio(shellp, argv, text, len, bp); if (ret == TRUE) { eerase(); if (lforw(bp->b_headp) == bp->b_headp) addline(bp, "(Shell command succeeded with no output)"); } free(text); return (ret); }
/* * kill the buffer pointed to by bp */ int zotbuf(struct buffer *bp) { struct buffer *bp1; struct buffer *bp2; int s; if (bp->b_nwnd != 0) { /* Error if on screen. */ mlwrite("Buffer is being displayed"); return FALSE; } if ((s = bclear(bp)) != TRUE) /* Blow text away. */ return s; free((char *) bp->b_linep); /* Release header line. */ bp1 = NULL; /* Find the header. */ bp2 = bheadp; while (bp2 != bp) { bp1 = bp2; bp2 = bp2->b_bufp; } bp2 = bp2->b_bufp; /* Next one in chain. */ if (bp1 == NULL) /* Unlink it. */ bheadp = bp2; else bp1->b_bufp = bp2; free((char *) bp); /* Release buffer block */ return TRUE; }
/* ARGSUSED */ int apropos_command(int f, int n) { struct buffer *bp; struct list *fnames, *el; char string[32]; if (eread("apropos: ", string, sizeof(string), EFNUL | EFNEW) == NULL) return (ABORT); /* FALSE means we got a 0 character string, which is fine */ bp = bfind("*help*", TRUE); if (bclear(bp) == FALSE) return (FALSE); fnames = complete_function_list(""); for (el = fnames; el != NULL; el = el->l_next) { char buf[32]; if (strstr(el->l_name, string) == NULL) continue; buf[0] = '\0'; findbind(fundamental_map, name_function(el->l_name), buf, sizeof(buf)); if (addlinef(bp, "%-32s%s", el->l_name, buf) == FALSE) { free_file_list(fnames); return (FALSE); } } free_file_list(fnames); return (popbuftop(bp, WNONE)); }
/* kill the buffer pointed to by bp */ int zotbuf (BUFFER *bp) { BUFFER *bp1, *bp2; int s; if (bp->b_nwnd != 0) { /* Error if on screen */ mlwrite ("Buffer is being displayed"); return (FALSE); } if ((s = bclear (bp)) != TRUE) /* Blow text away */ return (s); free (bp->b_linep); /* Release header line */ bp1 = 0; /* Find the header */ bp2 = bheadp; while (bp2 != bp) { bp1 = bp2; bp2 = bp2->b_bufp; } bp2 = bp2->b_bufp; /* Next one in chain */ if (bp1 == NULL) /* Unlink it */ bheadp = bp2; else bp1->b_bufp = bp2; free (bp); /* Release buffer block */ return (TRUE); }
/* kill the buffer pointed to by bp */ int zotbuf (BUFFER *bp) { BUFFER *bp1, *bp2; int s; /* we ony get here if there is only *scratch* left */ if (bp->b_nwnd != 0) return (FALSE); /* fail silently */ if ((s = bclear (bp)) != TRUE) /* Blow text away */ return (s); free (bp->b_linep); /* Release header line */ bp1 = 0; /* Find the header */ bp2 = bheadp; while (bp2 != bp) { bp1 = bp2; bp2 = bp2->b_bufp; } bp2 = bp2->b_bufp; /* Next one in chain */ if (bp1 == NULL) /* Unlink it */ bheadp = bp2; else bp1->b_bufp = bp2; free (bp); /* Release buffer block */ return (TRUE); }
/* * storeproc: * Set up a procedure buffer and flag to store all * executed command lines there * * int f; default flag * int n; macro number to use */ int storeproc(int f, int n) { struct buffer *bp; /* pointer to macro buffer */ int status; /* return status */ char bname[NBUFN]; /* name of buffer to use */ /* a numeric argument means its a numbered macro */ if (f == TRUE) return storemac(f, n); /* get the name of the procedure */ if ((status = mlreply("Procedure name: ", &bname[1], NBUFN - 2)) != TRUE) return status; /* construct the macro buffer name */ bname[0] = '*'; strcat(bname, "*"); /* set up the new macro buffer */ if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { mlwrite("Can not create macro"); return FALSE; } /* and make sure it is empty */ bclear(bp); /* and set the macro store pointers to it */ mstore = TRUE; bstore = bp; 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; int status, i, ro = FALSE; PF *ael; /* 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) { ewprintf("File is not readable: %s", fname); return (FALSE); } for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { if ((fisdir(fname)) != TRUE) { 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; /* * We need to set the READONLY flag after we insert the file, * unless the file is a directory. */ if (access(fname, W_OK) && errno != ENOENT) ro = TRUE; if (fisdir(fname) == TRUE) ro = TRUE; if (ro == TRUE) curbp->b_flag |= BFREADONLY; if (startrow) { gotoline(FFARG, startrow); startrow = 0; } undo_add_modified(); return (status); }
/* * This routine rebuilds the text for the * list buffers command. Return pointer * to new list if everything works. * Return NULL if there is an error (if * there is no memory). */ static struct buffer * makelist(void) { int w = ncol / 2; struct buffer *bp, *blp; struct line *lp; if ((blp = bfind("*Buffer List*", TRUE)) == NULL) return (NULL); if (bclear(blp) != TRUE) return (NULL); blp->b_flag &= ~BFCHG; /* Blow away old. */ blp->b_flag |= BFREADONLY; listbuf_ncol = ncol; /* cache ncol for listbuf_goto_buffer */ if (addlinef(blp, "%-*s%s", w, " MR Buffer", "Size File") == FALSE || addlinef(blp, "%-*s%s", w, " -- ------", "---- ----") == FALSE) return (NULL); for (bp = bheadp; bp != NULL; bp = bp->b_bufp) { RSIZE nbytes; nbytes = 0; /* Count bytes in buf. */ if (bp != blp) { lp = bfirstlp(bp); while (lp != bp->b_headp) { nbytes += llength(lp) + 1; lp = lforw(lp); } if (nbytes) nbytes--; /* no bonus newline */ } if (addlinef(blp, "%c%c%c %-*.*s%c%-6d %-*s", (bp == curbp) ? '.' : ' ', /* current buffer ? */ ((bp->b_flag & BFCHG) != 0) ? '*' : ' ', /* changed ? */ ((bp->b_flag & BFREADONLY) != 0) ? ' ' : '*', w - 5, /* four chars already written */ w - 5, /* four chars already written */ bp->b_bname, /* buffer name */ strlen(bp->b_bname) < w - 5 ? ' ' : '$', /* truncated? */ nbytes, /* buffer size */ w - 7, /* seven chars already written */ bp->b_fname) == FALSE) return (NULL); } blp->b_dotp = bfirstlp(blp); /* put dot at beginning of * buffer */ blp->b_doto = 0; return (blp); /* All done */ }
/* Customized selective data location */ static int init_percd_select(uint32 session_base_select) { int i; /* Start off with no cached blocks */ bclear(); /* Grab and check the volume descriptor */ i = bread(session_base_select + 16 - 150); if (i < 0) return i; if (memcmp((char*)cache[i]->data, "\01CD001", 6)) { printf("fs_iso9660: disc is not iso9660\r\n"); return -1; } /* Locate the root directory */ memcpy(&root_dirent, cache[i]->data+156, sizeof(iso_dirent_t)); root_extent = iso_733(root_dirent.extent); root_size = iso_733(root_dirent.size); return 0; }
/* ARGSUSED */ static int theo(int f, int n) { struct buffer *bp; struct mgwin *wp; bp = bfind("theo", TRUE); if (bclear(bp) != TRUE) return (FALSE); bp->b_modes[0] = name_mode("fundamental"); bp->b_modes[1] = name_mode("theo"); bp->b_nmodes = 1; if ((wp = popbuf(bp, WNONE)) == NULL) return (FALSE); curbp = bp; curwp = wp; return (TRUE); }
/* ARGSUSED */ int wallchart(int f, int n) { int m; struct buffer *bp; bp = bfind("*help*", TRUE); if (bclear(bp) != TRUE) /* clear it out */ return (FALSE); bp->b_flag |= BFREADONLY; for (m = curbp->b_nmodes; m > 0; m--) { if ((addlinef(bp, "Local keybindings for mode %s:", curbp->b_modes[m]->p_name) == FALSE) || (showall(bp, curbp->b_modes[m]->p_map, "") == FALSE) || (addline(bp, "") == FALSE)) return (FALSE); } if ((addline(bp, "Global bindings:") == FALSE) || (showall(bp, fundamental_map, "") == FALSE)) return (FALSE); return (popbuftop(bp, WNONE)); }
/* * storemac: * Set up a macro buffer and flag to store all * executed command lines there * * int f; default flag * int n; macro number to use */ int storemac(int f, int n) { struct buffer *bp; /* pointer to macro buffer */ char bname[NBUFN]; /* name of buffer to use */ /* must have a numeric argument to this function */ if (f == FALSE) { mlwrite("No macro specified"); return FALSE; } /* range check the macro number */ if (n < 1 || n > 40) { mlwrite("Macro number out of range"); return FALSE; } /* construct the macro buffer name */ strcpy(bname, "*Macro xx*"); bname[7] = '0' + (n / 10); bname[8] = '0' + (n % 10); /* set up the new macro buffer */ if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) { mlwrite("Can not create macro"); return FALSE; } /* and make sure it is empty */ bclear(bp); /* and set the macro store pointers to it */ mstore = TRUE; bstore = bp; return TRUE; }
/*ARGSUSED */ int diffbuffer(int f, int n) { struct buffer *bp; struct line *lp, *lpend; size_t len; int ret; char *text, *ttext; char * const argv[] = {DIFFTOOL, "-u", "-p", curbp->b_fname, "-", (char *)NULL}; len = 0; /* C-u is not supported */ if (n > 1) return (ABORT); if (access(DIFFTOOL, X_OK) != 0) { dobeep(); ewprintf("%s not found or not executable.", DIFFTOOL); return (FALSE); } if (curbp->b_fname[0] == 0) { dobeep(); ewprintf("Cannot diff buffer not associated with any files."); return (FALSE); } lpend = curbp->b_headp; for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) { len+=llength(lp); if (lforw(lp) != lpend) /* no implied \n on last line */ len++; } if ((text = calloc(len + 1, sizeof(char))) == NULL) { dobeep(); ewprintf("Cannot allocate memory."); return (FALSE); } ttext = text; for (lp = lforw(lpend); lp != lpend; lp = lforw(lp)) { if (llength(lp) != 0) { memcpy(ttext, ltext(lp), llength(lp)); ttext += llength(lp); } if (lforw(lp) != lpend) /* no implied \n on last line */ *ttext++ = '\n'; } bp = bfind("*Diff*", TRUE); bp->b_flag |= BFREADONLY; if (bclear(bp) != TRUE) { free(text); return (FALSE); } ret = pipeio(DIFFTOOL, argv, text, len, bp); if (ret == TRUE) { eerase(); if (lforw(bp->b_headp) == bp->b_headp) addline(bp, "Diff finished (no differences)."); } free(text); return (ret); }
/* * Read file "fname" into the current buffer, blowing away any text * found there. Called by both the read and find commands. Return * the final status of the read. Also called by the mainline, to * read in a file specified on the command line as an argument. * The command bound to M-FNR is called after the buffer is set up * and before it is read. * * char fname[]; name of file to read * int lockfl; check for file locks? */ int readin(char *fname, int lockfl) { struct line *lp1; struct line *lp2; int i; struct window *wp; struct buffer *bp; int s; int nbytes; int nline; char mesg[NSTRING]; #if (FILOCK && BSD) || SVR4 if (lockfl && lockchk(fname) == ABORT) #if PKCODE { s = FIOFNF; bp = curbp; strcpy(bp->b_fname, ""); goto out; } #else return ABORT; #endif #endif #if CRYPT s = resetkey(); if (s != TRUE) return s; #endif bp = curbp; /* Cheap. */ if ((s = bclear(bp)) != TRUE) /* Might be old. */ return s; bp->b_flag &= ~(BFINVS | BFCHG); strcpy(bp->b_fname, fname); /* let a user macro get hold of things...if he wants */ execute(META | SPEC | 'R', FALSE, 1); if ((s = ffropen(fname)) == FIOERR) /* Hard file open. */ goto out; if (s == FIOFNF) { /* File not found. */ mlwrite("(New file)"); goto out; } /* read the file in */ mlwrite("(Reading file)"); nline = 0; while ((s = ffgetline()) == FIOSUC) { nbytes = strlen(fline); if ((lp1 = lalloc(nbytes)) == NULL) { s = FIOMEM; /* Keep message on the */ break; /* display. */ } #if PKCODE if (nline > MAXNLINE) { s = FIOMEM; break; } #endif lp2 = lback(curbp->b_linep); lp2->l_fp = lp1; lp1->l_fp = curbp->b_linep; lp1->l_bp = lp2; curbp->b_linep->l_bp = lp1; for (i = 0; i < nbytes; ++i) lputc(lp1, i, fline[i]); ++nline; } ffclose(); /* Ignore errors. */ strcpy(mesg, "("); if (s == FIOERR) { strcat(mesg, "I/O ERROR, "); curbp->b_flag |= BFTRUNC; } if (s == FIOMEM) { strcat(mesg, "OUT OF MEMORY, "); curbp->b_flag |= BFTRUNC; } sprintf(&mesg[strlen(mesg)], "Read %d line", nline); if (nline != 1) strcat(mesg, "s"); strcat(mesg, ")"); mlwrite(mesg); out: for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_linep = lforw(curbp->b_linep); wp->w_dotp = lforw(curbp->b_linep); wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_flag |= WFMODE | WFHARD; } } if (s == FIOERR || s == FIOFNF) /* False if error. */ return FALSE; return TRUE; }
int killbuffer(struct buffer *bp) { struct buffer *bp1; struct buffer *bp2; struct mgwin *wp; int s; struct undo_rec *rec; /* * Find some other buffer to display. Try the alternate buffer, * then the first different buffer in the buffer list. If there's * only one buffer, create buffer *scratch* and make it the alternate * buffer. Return if *scratch* is only buffer... */ if ((bp1 = bp->b_altb) == NULL) { /* only one buffer. see if it's *scratch* */ if (bp == bfind("*scratch*", FALSE)) return (TRUE); /* create *scratch* for alternate buffer */ if ((bp1 = bfind("*scratch*", TRUE)) == NULL) return (FALSE); } if ((s = bclear(bp)) != TRUE) return (s); for (wp = wheadp; bp->b_nwnd > 0; wp = wp->w_wndp) { if (wp->w_bufp == bp) { bp2 = bp1->b_altb; /* save alternate buffer */ if (showbuffer(bp1, wp, WFMODE | WFFRAME | WFFULL)) bp1->b_altb = bp2; else bp1 = bp2; } } if (bp == curbp) curbp = bp1; free(bp->b_headp); /* Release header line. */ bp2 = NULL; /* Find the header. */ bp1 = bheadp; while (bp1 != bp) { if (bp1->b_altb == bp) bp1->b_altb = (bp->b_altb == bp1) ? NULL : bp->b_altb; bp2 = bp1; bp1 = bp1->b_bufp; } bp1 = bp1->b_bufp; /* Next one in chain. */ if (bp2 == NULL) /* Unlink it. */ bheadp = bp1; else bp2->b_bufp = bp1; while (bp1 != NULL) { /* Finish with altb's */ if (bp1->b_altb == bp) bp1->b_altb = (bp->b_altb == bp1) ? NULL : bp->b_altb; bp1 = bp1->b_bufp; } while ((rec = TAILQ_FIRST(&bp->b_undo))) { TAILQ_REMOVE(&bp->b_undo, rec, next); free_undo_record(rec); } free(bp->b_bname); /* Release name block */ free(bp); /* Release buffer block */ return (TRUE); }
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) { dobeep(); ewprintf("Can't change dir to %s", bp->b_cwd); return (NULL); } if ((fpipe = popen(qcmd, "r")) == NULL) { dobeep(); 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) { dobeep(); ewprintf("Can't change dir back to %s", cwd); return (NULL); } return (bp); }
/* * 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, ro = FALSE; 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; } } /* 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 makelist(int iflag) { char *cp1; char *cp2; int c; struct buffer *bp; struct line *lp; int s; int i; long nbytes; /* # of bytes in current buffer */ char b[7 + 1]; char line[MAXLINE]; blistp->b_flag &= ~BFCHG; /* Don't complain! */ if ((s = bclear(blistp)) != TRUE) /* Blow old text away */ return s; strcpy(blistp->b_fname, ""); if (addline("ACT MODES Size Buffer File") == FALSE || addline("--- ----- ---- ------ ----") == FALSE) return FALSE; bp = bheadp; /* For all buffers */ /* build line to report global mode settings */ cp1 = &line[0]; *cp1++ = ' '; *cp1++ = ' '; *cp1++ = ' '; *cp1++ = ' '; /* output the mode codes */ for (i = 0; i < NUMMODES; i++) if (gmode & (1 << i)) *cp1++ = modecode[i]; else *cp1++ = '.'; strcpy(cp1, " Global Modes"); if (addline(line) == FALSE) return FALSE; /* output the list of buffers */ while (bp != NULL) { /* skip invisable buffers if iflag is false */ if (((bp->b_flag & BFINVS) != 0) && (iflag != TRUE)) { bp = bp->b_bufp; continue; } cp1 = &line[0]; /* Start at left edge */ /* output status of ACTIVE flag (has the file been read in? */ if (bp->b_active == TRUE) /* "@" if activated */ *cp1++ = '@'; else *cp1++ = ' '; /* output status of changed flag */ if ((bp->b_flag & BFCHG) != 0) /* "*" if changed */ *cp1++ = '*'; else *cp1++ = ' '; /* report if the file is truncated */ if ((bp->b_flag & BFTRUNC) != 0) *cp1++ = '#'; else *cp1++ = ' '; *cp1++ = ' '; /* space */ /* output the mode codes */ for (i = 0; i < NUMMODES; i++) { if (bp->b_mode & (1 << i)) *cp1++ = modecode[i]; else *cp1++ = '.'; } *cp1++ = ' '; /* Gap. */ nbytes = 0L; /* Count bytes in buf. */ lp = lforw(bp->b_linep); while (lp != bp->b_linep) { nbytes += (long) llength(lp) + 1L; lp = lforw(lp); } ltoa(b, 7, nbytes); /* 6 digit buffer size. */ cp2 = &b[0]; while ((c = *cp2++) != 0) *cp1++ = c; *cp1++ = ' '; /* Gap. */ cp2 = &bp->b_bname[0]; /* Buffer name */ while ((c = *cp2++) != 0) *cp1++ = c; cp2 = &bp->b_fname[0]; /* File name */ if (*cp2 != 0) { while (cp1 < &line[3 + 1 + 5 + 1 + 6 + 4 + NBUFN]) *cp1++ = ' '; while ((c = *cp2++) != 0) { if (cp1 < &line[MAXLINE - 1]) *cp1++ = c; } } *cp1 = 0; /* Add to the buffer. */ if (addline(line) == FALSE) return FALSE; bp = bp->b_bufp; } return TRUE; /* All done */ }
/* * Do completion on a list of objects, listing instead of completing. */ static int complt_list(int flags, char *buf, int cpos) { struct list *lh, *lh2, *lh3; struct list *wholelist = NULL; struct buffer *bp; int i, maxwidth, width; int preflen = 0; int oldrow = ttrow; int oldcol = ttcol; int oldhue = tthue; char *linebuf; size_t linesize, len; char *cp; lh = NULL; ttflush(); /* The results are put into a completion buffer. */ bp = bfind("*Completions*", TRUE); if (bclear(bp) == FALSE) return (FALSE); /* * First get the list of objects. This list may contain only * the ones that complete what has been typed, or may be the * whole list of all objects of this type. They are filtered * later in any case. Set wholelist if the list has been * cons'ed up just for us, so we can free it later. We have * to copy the buffer list for this function even though we * didn't for complt. The sorting code does destructive * changes to the list, which we don't want to happen to the * main buffer list! */ if ((flags & EFBUF) != 0) wholelist = lh = copy_list(&(bheadp->b_list)); else if ((flags & EFFUNC) != 0) { buf[cpos] = '\0'; wholelist = lh = complete_function_list(buf); } else if ((flags & EFFILE) != 0) { buf[cpos] = '\0'; wholelist = lh = make_file_list(buf); /* * We don't want to display stuff up to the / for file * names preflen is the list of a prefix of what the * user typed that should not be displayed. */ cp = strrchr(buf, '/'); if (cp) preflen = cp - buf + 1; } else panic("broken complt call: flags"); /* * Sort the list, since users expect to see it in alphabetic * order. */ lh2 = lh; while (lh2 != NULL) { lh3 = lh2->l_next; while (lh3 != NULL) { if (strcmp(lh2->l_name, lh3->l_name) > 0) { cp = lh2->l_name; lh2->l_name = lh3->l_name; lh3->l_name = cp; } lh3 = lh3->l_next; } lh2 = lh2->l_next; } /* * First find max width of object to be displayed, so we can * put several on a line. */ maxwidth = 0; lh2 = lh; while (lh2 != NULL) { for (i = 0; i < cpos; ++i) { if (buf[i] != lh2->l_name[i]) break; } if (i == cpos) { width = strlen(lh2->l_name); if (width > maxwidth) maxwidth = width; } lh2 = lh2->l_next; } maxwidth += 1 - preflen; /* * Now do the display. Objects are written into linebuf until * it fills, and then put into the help buffer. */ linesize = MAX(ncol, maxwidth) + 1; if ((linebuf = malloc(linesize)) == NULL) { free_file_list(wholelist); return (FALSE); } width = 0; /* * We're going to strlcat() into the buffer, so it has to be * NUL terminated. */ linebuf[0] = '\0'; for (lh2 = lh; lh2 != NULL; lh2 = lh2->l_next) { for (i = 0; i < cpos; ++i) { if (buf[i] != lh2->l_name[i]) break; } /* if we have a match */ if (i == cpos) { /* if it wraps */ if ((width + maxwidth) > ncol) { addline(bp, linebuf); linebuf[0] = '\0'; width = 0; } len = strlcat(linebuf, lh2->l_name + preflen, linesize); width += maxwidth; if (len < width && width < linesize) { /* pad so the objects nicely line up */ memset(linebuf + len, ' ', maxwidth - strlen(lh2->l_name + preflen)); linebuf[width] = '\0'; } } } if (width > 0) addline(bp, linebuf); free(linebuf); /* * Note that we free lists only if they are put in wholelist lists * that were built just for us should be freed. However when we use * the buffer list, obviously we don't want it freed. */ free_file_list(wholelist); popbuftop(bp, WEPHEM); /* split the screen and put up the help * buffer */ update(CMODE); /* needed to make the new stuff actually * appear */ ttmove(oldrow, oldcol); /* update leaves cursor in arbitrary place */ ttcolor(oldhue); /* with arbitrary color */ ttflush(); return (0); }
/* * 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); }
/* * This routine rebuilds the text in the special secret buffer that holds the * buffer list. It is called by the list buffers command. Return TRUE if * everything works. Return FALSE if there is an error (if there is no * memory). */ int makelist () { BUFFER *bp; LINE *lp; char *cp1, *cp2; char b[8], line[128]; int nbytes, s, c; blistp->b_flag &= ~BFCHG; /* Don't complain! */ if ((s = bclear (blistp)) != TRUE) /* Blow old text away */ return (s); strncpy (blistp->b_fname, "", 1); if (addline ("ACV Size Buffer File") == FALSE || addline ("--- ------- ------ ----") == FALSE) return (FALSE); bp = bheadp; /* build line to report global mode settings */ cp1 = &line[0]; *cp1++ = ' '; *cp1++ = ' '; *cp1++ = ' '; *cp1++ = ' '; /* output the list of buffers */ while (bp != 0) { if ((bp->b_flag & BFTEMP) != 0) { /* Skip magic ones */ bp = bp->b_bufp; continue; } cp1 = &line[0]; /* Start at left edge */ /* output status of ACTIVE flag (has the file been read in? */ if (bp->b_active == TRUE) /* "@" if activated */ *cp1++ = '@'; else *cp1++ = ' '; /* output status of changed flag */ if ((bp->b_flag & BFCHG) != 0) /* "*" if changed */ *cp1++ = '*'; else *cp1++ = ' '; /* output status of readonly flag */ if ((bp->b_flag & BFRO) != 0) /* "%" if view mode */ *cp1++ = '%'; else *cp1++ = ' '; *cp1++ = ' '; /* Gap */ nbytes = 0; /* Count bytes in buf */ lp = lforw (bp->b_linep); while (lp != bp->b_linep) { nbytes += llength (lp) + 1; lp = lforw (lp); } itoa (b, 7, nbytes); /* 7 digit buffer size */ cp2 = &b[0]; while ((c = *cp2++) != 0) *cp1++ = (char)c; *cp1++ = ' '; /* Gap */ cp2 = &bp->b_bname[0]; /* Buffer name */ while ((c = *cp2++) != 0) *cp1++ = (char)c; cp2 = &bp->b_fname[0]; /* File name */ if (*cp2 != 0) { while (cp1 < &line[3 + 1 + 7 + 1 + NBUFN + 1]) /* ACV, space, size, space, bufname, space */ *cp1++ = ' '; while ((c = *cp2++) != 0) { if (cp1 < &line[128 - 1]) *cp1++ = (char)c; } } *cp1 = 0; /* Add to the buffer */ if (addline (line) == FALSE) return (FALSE); bp = bp->b_bufp; } return (TRUE); /* All done */ }
/* * Read file "fname" into the current buffer, blowing away any text found * there. Called by both the read and find commands. Return the final status * of the read. Also called by the mainline, to read in a file specified on * the command line as an argument. */ int readin(char fname[]) { LINE *lp1, *lp2; WINDOW *wp; BUFFER *bp; char line[NLINE]; int nbytes, s, i; int nline = 0; /* initialize here to silence a gcc warning */ int lflag; /* any lines longer than allowed? */ bp = curbp; /* Cheap */ if ((s = bclear(bp)) != TRUE) /* Might be old */ return (s); bp->b_flag &= ~(BFTEMP | BFCHG); strncpy(bp->b_fname, fname, NFILEN); if ((s = ffropen(fname)) == FIOERR) /* Hard file open */ goto out; if (s == FIOFNF) { /* File not found */ mlwrite("[New file]"); goto out; } mlwrite("[Reading file]"); lflag = FALSE; while ((s = ffgetline(line, NLINE)) == FIOSUC || s == FIOLNG) { if (s == FIOLNG) lflag = TRUE; nbytes = strlen(line); if ((lp1 = lalloc(nbytes)) == NULL) { s = FIOERR; /* Keep message on the display */ break; } lp2 = lback(curbp->b_linep); lp2->l_fp = lp1; lp1->l_fp = curbp->b_linep; lp1->l_bp = lp2; curbp->b_linep->l_bp = lp1; for (i = 0; i < nbytes; ++i) lputc(lp1, i, line[i]); ++nline; } ffclose(); /* Ignore errors */ if (s == FIOEOF) { /* Don't zap message! */ if (nline != 1) mlwrite("[Read %d lines]", nline); else mlwrite("[Read 1 line]"); } if (lflag) { if (nline != 1) mlwrite("[Read %d lines: Long lines wrapped]", nline); else mlwrite("[Read 1 line: Long lines wrapped]"); } curwp->w_bufp->b_lines = nline; out: for (wp = wheadp; wp != NULL; wp = wp->w_wndp) { if (wp->w_bufp == curbp) { wp->w_linep = lforw(curbp->b_linep); wp->w_dotp = lforw(curbp->b_linep); wp->w_doto = 0; wp->w_markp = NULL; wp->w_marko = 0; wp->w_flag |= WFMODE | WFHARD; } } if (s == FIOERR || s == FIOFNF) /* False if error */ return (FALSE); return (TRUE); }
/* 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 }