home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-06 | 75.0 KB | 2,722 lines |
- Newsgroups: comp.sources.unix
- From: klin@iat.uni-paderborn.de (Peter Klingebiel)
- Subject: v26i069: utree - screen oriented filesystem utility (V3.03b-um), Part06/08
- Sender: unix-sources-moderator@pa.dec.com
- Approved: vixie@pa.dec.com
-
- Submitted-By: klin@iat.uni-paderborn.de (Peter Klingebiel)
- Posting-Number: Volume 26, Issue 69
- Archive-Name: utree/part06
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 6 (of 8)."
- # Contents: src/file.c src/term.c
- # Wrapped by vixie@cognition.pa.dec.com on Mon Sep 7 14:39:57 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/file.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/file.c'\"
- else
- echo shar: Extracting \"'src/file.c'\" \(41484 characters\)
- sed "s/^X//" >'src/file.c' <<'END_OF_FILE'
- X/*
- X * FILE.C
- X * UTREE file menu routines.
- X * 3.01-um klin, Tue Jun 4 14:20:31 1991
- X * klin, Tue Oct 15 14:02:37 1991, Handling of symlinks changed
- X * klin, Sat Oct 26 15:07:06 1991, Copying and moving changed
- X * Sorting and zooming changed
- X * Select directories added
- X * 3.02-um klin, Fri Nov 1 10:46:14 1991, Screen layout changed
- X * Marking files changed
- X * Bug in edit() deleted
- X * klin, Sun Nov 24 19:30:43 1991, Cd to current directory before
- X * executing some commands
- X * Video attributes changed
- X * 3.03-um klin, Tue Feb 11 19:39:09 1992, Screen layout changed,
- X * Variables and filetype commands
- X * changed
- X * klin, Sun Feb 23 17:32:31 1992, Key handling and key bindings
- X * changed
- X * klin, Fri Mar 6 08:18:38 1992, Minor changes in execute()
- X *
- X * Copyright (c) 1991/92 by Peter Klingebiel & UNIX Magazin Muenchen.
- X * For copying and distribution information see the file COPYRIGHT.
- X */
- X#ifndef lint
- static char sccsid[] = "@(#) utree 3.03-um (klin) Mar 6 1992 file.c";
- X#endif /* !lint */
- X
- X#include "defs.h"
- X
- X/* ---- Local variables and definitions ------------------------------- */
- X
- LOCAL int flast; /* Last current file */
- LOCAL int fmark; /* Marked file */
- LOCAL int nscroll; /* Lines to scroll */
- X
- X/* Default file menu commands in help line */
- LOCAL char *fmline =
- X" Help Copy Edit Find Grep Move List Print Remove Stat Tag Untag View Quit";
- LOCAL char *menuline = NULL;
- X
- X#define CUR(c) ((c) >= 'a') /* Command works on current file only */
- X
- X/* ---- External variables and functions ------------------------------ */
- X
- XEXTRN char *selectdir();
- X
- X/* ---- Local/global functions and procedures ------------------------- */
- X
- X/*
- X * FILE SCREEN UPDATE AND REFRESH
- X */
- X
- X/* Show file list from file f to file t */
- LOCAL VOID showfiles(f, t, c)
- X register int f, t, c;
- X{
- X if(c) { /* Clear file window */
- X (void) cursorxy(0, firstline);
- X clearwindow(firstline, lastline);
- X }
- X while(f < CNFIL && f < t && FFROW(cdlist, f) <= lastline)
- X putfile(cdlist, f++, FF_TAG);
- X
- X} /* showfiles() */
- X
- X/* Update file screen */
- LOCAL VOID updatefiles()
- X{
- X if(fileflag == SF_FULL) /* Full update */
- X clearscreen();
- X if(fileflag & SF_ECHO) /* Echo line */
- X if(CZOOM)
- X (void) putecho("%s/%s: %d file(s)", CPNAM, CZOOM, CNFIL);
- X else
- X (void) putecho("%s/*: %d file(s) %d dir(s)", CPNAM, CNFIL, CNDIR);
- X if(fileflag & SF_HELP) /* Help line */
- X putmenu("FILE:", menuline);
- X if(fileflag & SF_TREE) { /* File window */
- X if(CANSCROLL && nscroll < 0 && nscroll > (firstline-lastline)) {
- X (void) windowup(firstline, lastline, -nscroll);
- X showfiles(CFTOP+fperpage-fperline+(nscroll*fperline), CFTOP+fperpage, 0);
- X if(flast >= 0)
- X putfile(cdlist, flast, FF_TAG);
- X }
- X else if(CANSCROLL && nscroll > 0 && nscroll < (lastline-firstline)) {
- X (void) windowdown(firstline, lastline, nscroll);
- X showfiles(CFTOP, CFTOP + (nscroll * fperline) + fperline, 0);
- X if(flast >= 0)
- X putfile(cdlist, flast, FF_TAG);
- X }
- X else
- X showfiles(CFTOP, CNFIL, fileflag != SF_FULL);
- X nscroll = 0;
- X fileflag |= SF_LIST;
- X }
- X else if(fileflag & SF_LAST && flast >= 0) /* Last file */
- X putfile(cdlist, flast, FF_TAG);
- X if((fileflag & SF_LIST) && CNFIL > 0) { /* Current file */
- X putfile(cdlist, CFCUR, FF_TAG);
- X flast = CFCUR;
- X }
- X if(CNFIL > 0) /* Position to current file */
- X (void) cursorxy(FFCOL(cdlist, CFCUR), FFROW(cdlist, CFCUR));
- X else
- X (void) cursorxy(0, firstline);
- X fileflag = 0; /* Reset fileflag */
- X
- X} /* updatefiles() */
- X
- X/*
- X * MARK/TAG FILE
- X */
- X
- X/* Set mark w on file f */
- LOCAL VOID setmark(f, w)
- X register int f, w;
- X{
- X if(f >= CFTOP && f < (CFTOP + fperpage)) {
- X putfile(cdlist, f, w);
- X (void) cursorxy(FFCOL(cdlist, f), FFROW(cdlist, f));
- X flushout();
- X }
- X
- X} /* setmark() */
- X
- X/* Reset mark on file f */
- LOCAL VOID unsetmark(f)
- X register int f;
- X{
- X if(f >= CFTOP && f < (CFTOP + fperpage)) {
- X putfile(cdlist, f, FF_TAG);
- X (void) cursorxy(FFCOL(cdlist, f), FFROW(cdlist, f));
- X flushout();
- X }
- X
- X} /* unsetmark() */
- X
- X/* Tag single file f */
- LOCAL VOID tagfile(f)
- X register int f;
- X{
- X FITAG(cdlist, f) = FF_TAG;
- X ++CNTAG;
- X setmark(f, FF_TAG);
- X
- X} /* tagfile() */
- X
- X/* Untag single file f */
- LOCAL VOID untagfile(f)
- X register int f;
- X{
- X FITAG(cdlist, f) = FF_NONE;
- X if(CNTAG > 0)
- X --CNTAG;
- X
- X} /* untagfile() */
- X
- X/*
- X * MOVE IN FILELIST
- X */
- X
- X/* Go forward or backward in file list */
- GLOBL int gofile(dp, dir)
- X register dlist *dp;
- X register int dir;
- X{
- X register int l;
- X
- X if(dir > 0 && (DFCUR(dp) + 1) < DNFIL(dp)) { /* Next file */
- X ++DFCUR(dp);
- X fileflag |= SF_LIST;
- X /* Out of bounds: Search for new top file */
- X if(DFCUR(dp) >= (DFTOP(dp)+fperpage) && (DFTOP(dp)+fperpage) < DNFIL(dp)) {
- X l = (lastline - firstline) / 2;
- X while(l-- > 0 && (DFTOP(dp) + fperpage) < DNFIL(dp)) {
- X DFTOP(dp) += fperline;
- X --nscroll;
- X }
- X fileflag |= SF_TREE;
- X }
- X else
- X fileflag |= SF_LAST;
- X }
- X else if(dir < 0 && DFCUR(dp) > 0) { /* Previous file */
- X --DFCUR(dp);
- X fileflag |= SF_LIST;
- X /* Out of bounds: Search for new top file */
- X if(DFCUR(dp) < DFTOP(dp) && DFTOP(dp) > 0) {
- X l = (lastline - firstline) / 2;
- X while(l-- > 0 && DFTOP(dp) > 0) {
- X DFTOP(dp) -= fperline;
- X ++nscroll;
- X }
- X fileflag |= SF_TREE;
- X }
- X else
- X fileflag |= SF_LAST;
- X }
- X else
- X return(0);
- X return(1);
- X
- X} /* gofile() */
- X
- X/*
- X * SCROLL FILE LIST
- X */
- X
- X/* Scroll up or down file list */
- LOCAL int scrollfile(dir)
- X register int dir;
- X{
- X if(dir < 0 && (CFTOP + fperpage) < CNFIL) { /* Scroll up */
- X CFTOP += fperline;
- X if(CANSCROLL) {
- X (void) windowup(firstline, lastline, 1);
- X showfiles(CFTOP + fperpage - fperline, CFTOP + fperpage, 0);
- X fileflag |= SF_MOVE;
- X }
- X else
- X fileflag |= SF_TREE;
- X if(CFCUR < CFTOP) {
- X CFCUR += fperline;
- X fileflag |= SF_LIST;
- X }
- X }
- X else if(dir > 0 && CFTOP > 0) { /* Scroll down */
- X CFTOP -= fperline;
- X if(CANSCROLL) {
- X (void) windowdown(firstline, lastline, 1);
- X showfiles(CFTOP, CFTOP + fperline, 0);
- X fileflag |= SF_MOVE;
- X }
- X else
- X fileflag |= SF_TREE;
- X if(CFCUR >= (CFTOP + fperpage)) {
- X CFCUR -= fperline;
- X fileflag |= SF_LIST;
- X }
- X }
- X else
- X return(0);
- X return(1);
- X
- X} /* scrollfile() */
- X
- X/*
- X * SELECT DIRECTORY
- X */
- LOCAL char *doselect(what)
- X register char *what;
- X{
- X register char *dn;
- X
- X dn = selectdir(what);
- X fileflag = SF_FULL;
- X fileflag &= ~(SF_HELP|SF_ECHO);
- X updatefiles();
- X return(dn);
- X
- X} /* doselect() */
- X
- X/*
- X * LIST FILE(S)
- X */
- X
- X/* List file(s) in current file list */
- LOCAL int list(t)
- X register int t;
- X{
- X char pat[PATLEN];
- X struct stat st;
- X register char *ct;
- X register int c, f, ff, l;
- X
- X if(CNFIL == 0) /* Nothing to list */
- X return(RV_OK);
- X
- X who = "LIST FILE";
- X if(t || CNTAG <= 0) {
- X puthelp("%s: Give file pattern (CR:all files)", who);
- X if((c = getpattern(pat, "List which files:")) < RV_NUL)
- X return(c);
- X else if(c == RV_NUL)
- X (void) strcpy(pat, "*");
- X t = 1;
- X }
- X
- X /* Show all matching files */
- X l = firstline;
- X ff = 0;
- X c = RV_OK;
- X for(f = 0; f < CNFIL; f++) {
- X if(( !t && ISTAG(cdlist, f)) || umatch(cdlist, f, pat) > 0) {
- X if((*statfun)(FFNAM(cdlist, f), &st) != 0)
- X continue;
- X if(l == firstline) {
- X if(ff > 0) {
- X puthelp("%s %s (CR:continue ELSE:quit)", who, pat);
- X c = hitakey("Continue listing ?", echoline, DA_NONE);
- X if( !(c == '\n' || c == ' '))
- X break;
- X }
- X fileflag = SF_FULL;
- X clearwindow(firstline, lastline);
- X }
- X ++ff;
- X ct = ctime(&st.st_mtime);
- X ct[strlen(ct) - 1] = '\0';
- X (void) putfxy(0, l, 0, "%s %8ld %s %s", fileaccess(&st), st.st_size, ct,
- X FFNAM(cdlist, f));
- X if(++l > lastline)
- X l = firstline;
- X }
- X }
- X
- X if(c >= RV_NUL) {
- X puthelp("%s %s", who, hitkey);
- X if(t)
- X (void) putecho("Listed %d file(s) matching %s", ff, pat);
- X else
- X (void) putecho("Listed %d tagged file(s)", ff);
- X c = hitakey(NULL);
- X }
- X return(c);
- X
- X} /* list() */
- X
- X/*
- X * SEARCH IN FILE(S)
- X */
- X
- X/* Search for pattern in file(s) */
- LOCAL int grep(one)
- X register int one;
- X{
- X char input[PATLEN];
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to search */
- X return(RV_OK);
- X
- X who = "GREP FILE";
- X puthelp("%s: Give pattern (CR:%s)", who, gpattern[0] ? gpattern : "quit");
- X c = putecho("Search for pattern in file:");
- X if((c = getline(input, sizeof(input), c, 0, NULL, GNULL, 0)) == RV_OK)
- X (void) strcpy(gpattern, input);
- X else if(c < RV_NUL || (c == RV_NUL && gpattern[0] == '\0'))
- X return(c);
- X
- X if( !one && CNTAG) { /* Tagged files */
- X c = RV_NUL; f = -1;
- X do {
- X ++f;
- X if(ISTAG(cdlist, f)) { /* File tagged */
- X untagfile(f);
- X setmark(f, FF_MARK);
- X (void) putecho("Searching in %s", FFNAM(cdlist, f));
- X flushout();
- X if((c = grepfile(cdlist, f)) == RV_OK) {
- X puthelp("%s (CR:next SP:select M:mark T:tag ELSE:quit)", who);
- X (void) putecho("Found \'%s\' -> %s:", gpattern, FFNAM(cdlist, f));
- X c = hitakey(NULL);
- X unsetmark(f);
- X if(c == 't') {
- X tagfile(f);
- X c = '\n';
- X }
- X else if(c == 'm') {
- X fmark = f;
- X c = '\n';
- X }
- X else if(c == ' ')
- X while(f != CFCUR)
- X (void) gofile(cdlist, f > CFCUR ? 1 : -1);
- X }
- X else
- X unsetmark(f);
- X }
- X } while(f < CNFIL && (c == RV_NUL || c == '\n'));
- X }
- X else if((c = grepfile(cdlist, CFCUR)) == RV_OK) { /* Current file */
- X puthelp("%s %s", who, hitkey);
- X (void) putecho("Found \'%s\'", gpattern);
- X c = hitakey(NULL);
- X }
- X
- X if(c)
- X return(c);
- X puthelp("%s: %s %s", who, gpattern, hitkey);
- X return(errequest(gpattern, "Not found"));
- X
- X} /* grep() */
- X
- X/*
- X * FIND FILE(S)
- X */
- X
- X/* Find file(s) in current file list */
- LOCAL int find(one)
- X register int one;
- X{
- X char input[PATLEN];
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to find */
- X return(RV_OK);
- X
- X who = "FIND FILE";
- X puthelp("%s: Give file pattern (CR:%s)", who, fpattern[0] ? fpattern : "quit");
- X if((c = getpattern(input, "Find which file:")) == RV_OK)
- X (void) strcpy(fpattern, input);
- X else if(c < RV_NUL || (c == RV_NUL && fpattern[0] == '\0'))
- X return(c);
- X
- X f = one ? CFCUR : -1;
- X do {
- X ++f;
- X if((c = findfile(cdlist, f)) == RV_OK) {
- X setmark(f, FF_MARK);
- X puthelp("%s (CR:next SP:select M:mark T:tag ELSE:quit)", who);
- X (void) putecho("Found %s:", FFNAM(cdlist, f));
- X c = hitakey(NULL);
- X unsetmark(f);
- X if(c == 't') {
- X tagfile(f);
- X c = '\n';
- X }
- X else if(c == 'm') {
- X fmark = f;
- X c = '\n';
- X }
- X else if(c == ' ')
- X while(f != CFCUR)
- X (void) gofile(cdlist, f > CFCUR ? 1 : -1);
- X }
- X } while(f < CNFIL && (c == RV_NUL || c == '\n'));
- X
- X if(c)
- X return(c);
- X
- X puthelp("%s: %s %s", who, fpattern, hitkey);
- X return(errequest(fpattern, "Not found"));
- X
- X} /* find() */
- X
- X/*
- X * FILE STATUS AND CHANGES
- X */
- X
- X/* Status information(s)/change(s) for current or tagged file(s) */
- LOCAL int status(one, s)
- X register int one, s;
- X{
- X register int f, c;
- X
- X if(CNFIL == 0) /* No need for status of nothing */
- X return(RV_OK);
- X
- X if( !one && CNTAG) { /* Tagged files */
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X if(s)
- X c = statusfile(FFNAM(cdlist, f), 1);
- X else {
- X setmark(f, FF_MARK);
- X c = infofile(f, CNTAG > 0);
- X unsetmark(f);
- X }
- X if( !(c == RV_NUL || c == '\n' || c == ' '))
- X break;
- X }
- X }
- X else {
- X if(s)
- X c = statusfile(FFNAM(cdlist, CFCUR), 1); /* Current files */
- X else
- X c = infofile(CFCUR, 0);
- X }
- X
- X if(buildflag) /* Rebuilding needed */
- X CFLAG = FL_CHG;
- X return(c);
- X
- X} /* status() */
- X
- X/* Display size and modification time of file f */
- LOCAL int infofile(f, h)
- X register int f, h;
- X{
- X struct stat st;
- X
- X who = "INFO FILE";
- X if((*statfun)(FFNAM(cdlist, f), &st)) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(FFNAM(cdlist, f), "Cannot stat"));
- X }
- X if(h)
- X puthelp("%s %s (CR:continue ELSE:quit)", who, FFNAM(cdlist, f));
- X else
- X puthelp("%s %s %s", who, FFNAM(cdlist, f), hitkey);
- X (void) putecho("Access:%s Size:%ld Date:%s",
- X fileaccess(&st), st.st_size, ctime(&st.st_mtime));
- X return(hitakey(NULL));
- X
- X} /* infofile() */
- X
- X/*
- X * MOVE OR RENAME FILE(S)
- X */
- X
- X/* Move current or tagged file(s) */
- LOCAL int move(one)
- X register int one;
- X{
- X struct stat st;
- X char name[NAMELEN];
- X register char *to;
- X register int f, c, req;
- X
- X if(CNFIL == 0) /* Nothing to move */
- X return(RV_OK);
- X
- X who = "MOVE FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X puthelp("%s: Give destination directory (CR:select one)", who);
- X c = putecho("Move tagged files to:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, CLIST, 0)) < RV_NUL)
- X return(c);
- X if(c == RV_OK) {
- X to = strcpy(name, pathname(name, CPNAM));
- X if((*statfun)(to, &st) < 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(name, "Cannot stat"));
- X }
- X else if(STFMT(&st) != S_IFDIR) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(name, "Is not a directory"));
- X }
- X }
- X else if((to = doselect("moving files")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X puthelp("%s (N:don't request Q:quit ELSE:request)", who);
- X (void) putecho("Request before moving to %s ?", to);
- X c = hitakey(NULL);
- X if(c == 'q' || c < RV_NUL)
- X return(c);
- X if(req = (c != 'n'))
- X puthelp("%s (Y:move Q:quit ELSE:don't move)", who);
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X setmark(f, FF_MARK);
- X c = movefile(cdlist, f, to, req);
- X unsetmark(f);
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X else { /* Current file */
- X puthelp("%s: Give destination (CR:select directory)", who);
- X c = putecho("Move file to:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, CLIST, 0)) < RV_NUL)
- X return(c);
- X else if(c == RV_OK)
- X to = strcpy(name, pathname(name, CPNAM));
- X else if((to = doselect("moving file")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X c = movefile(cdlist, CFCUR, to, 0);
- X }
- X
- X checkdlist(to); /* Directory needs checking */
- X ++buildflag; /* Set rebuild flags */
- X CFLAG = FL_CHG;
- X fileflag |= SF_ECHO|SF_HELP;
- X return(c);
- X
- X} /* move() */
- X
- X/*
- X * VIEW FILE(S)
- X */
- X
- X/* View current or tagged file(s) */
- LOCAL int view(one)
- X register int one;
- X{
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to view */
- X return(RV_OK);
- X
- X if( !one && CNTAG) { /* Tagged files */
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X if((c = viewfile(f, 0)) == 'n' || c < RV_NUL)
- X break;
- X }
- X }
- X else /* Current file */
- X c = viewfile(CFCUR, 1);
- X
- X return(c);
- X
- X} /* view() */
- X
- X/* View single file f */
- LOCAL int viewfile(f, one)
- X register int f, one;
- X{
- X char name[NAMELEN], buf[EXECLEN];
- X register FILE *file;
- X register int c, n;
- X
- X /* Check if viewing is allowed */
- X if( !isallowed(FFNAM(cdlist, f), (int) FMODE(cdlist, f)))
- X return(hitakey(NULL));
- X
- X who = "VIEW FILE";
- X /* Simple check for text or binary file. May fail! */
- X (void) strcpy(name, pathname(FFNAM(cdlist, f), CPNAM));
- X if(file = fopen(name, "r")) {
- X n = fread(buf, sizeof(char), 4, file);
- X (void) fclose(file);
- X }
- X else
- X return(errequest(FFNAM(cdlist, f), "Cannot open"));
- X
- X if(n <= 0) /* File is empty */
- X return(errequest(FFNAM(cdlist, f), "Is empty"));
- X else if(istextfile(buf, n)) { /* Text file */
- X (void) sprintf(buf, "%s %s %s", VARVAL(V_PG), VARVAL(V_PGO), name);
- X (void) callsystem(buf, 1, 1);
- X }
- X else { /* Binary file */
- X puthelp("%s (Y:hex dump ELSE:don't view)", who);
- X (void) putecho("File %s is not a text file, hex dump ?", FFNAM(cdlist, f));
- X if((c = hitakey(NULL)) != 'y')
- X return(c);
- X (void) sprintf(buf, "%s %s %s|%s %s", VARVAL(V_XD), VARVAL(V_XDO), name,
- X VARVAL(V_PG), VARVAL(V_PGO));
- X (void) callsystem(buf, 1, 1);
- X }
- X
- X if(one || CNTAG < 1)
- X return(hitakey("Viewing done (Hit a key)", lines-1, DA_REVERSE));
- X else
- X return(hitakey("Continue (N:no ELSE:yes) ?", lines-1, DA_REVERSE));
- X
- X} /* viewfile() */
- X
- X/* Simple check if a file is a text file */
- LOCAL int istextfile(s, n)
- X register char *s;
- X register int n;
- X{
- X while(--n > 0) { /* Simple check if all n chars */
- X if( !(isprint(*s) || isspace(*s))) /* are printable or whitespace */
- X return(0);
- X ++s;
- X }
- X return(1);
- X
- X} /* istextfile() */
- X
- X/*
- X * PRINT FILE(S)
- X */
- X
- X/* Print current or tagged file(s) */
- LOCAL int print(one)
- X register int one;
- X{
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to print */
- X return(RV_OK);
- X
- X who = "PRINT FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X setmark(f, FF_MARK);
- X puthelp("%s (Y:print Q:quit ELSE:don't print)", who);
- X c = printfile(f, 1);
- X unsetmark(f);
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X else /* Current file */
- X c = printfile(CFCUR, 0);
- X
- X if(c < RV_NUL || one || !CNTAG)
- X return(c);
- X puthelp("%s %s", who, hitkey);
- X return(hitakey("Printing done", echoline, DA_NONE));
- X
- X} /* print() */
- X
- X/* Print single file f with request if req is set */
- LOCAL int printfile(f, req)
- X register int f, req;
- X{
- X char name[NAMELEN], buf[EXECLEN];
- X register int c;
- X
- X (void) strcpy(name, pathname(FFNAM(cdlist, f), CPNAM));
- X if(req) {
- X (void) putecho("Print %s ?", name);
- X if((c = hitakey(NULL)) != 'y')
- X return(c);
- X }
- X (void) putecho("Printing %s", name);
- X (void) sprintf(buf, "%s %s %s", VARVAL(V_LP), VARVAL(V_LPO), name);
- X if((c = callsystem(buf, 0, 0)) != RV_OK)
- X return(errequest(FFNAM(cdlist, f), "Error in printing"));
- X return(RV_OK);
- X
- X} /* printfile() */
- X
- X/*
- X * REMOVE FILE(S)
- X */
- X
- X/* Remove current or tagged file(s) */
- LOCAL int remove(one)
- X register int one;
- X{
- X register int f, c, req;
- X
- X if(CNFIL == 0) /* Nothing to remove */
- X return(RV_OK);
- X
- X who = "REMOVE FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X if(CNTAG > 1) {
- X puthelp("%s (N:don't request Q:quit ELSE:request)", who);
- X c = hitakey("Request before removing ?", echoline, DA_NONE);
- X if(c == 'q' || c < RV_NUL)
- X return(c);
- X else if(req = (c != 'n'))
- X puthelp("%s (Y:remove Q:quit ELSE:don't remove)", who);
- X }
- X else
- X req = 1;
- X for(f = CNFIL - 1; f >= 0; f--) {
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X setmark(f, FF_MARK);
- X if((c = removefile(cdlist, f, req)) != RV_OK)
- X unsetmark(f);
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X }
- X else { /* Current file */
- X puthelp("%s (Y:remove ELSE:don't remove)", who);
- X c = removefile(cdlist, CFCUR, 1);
- X }
- X
- X return(c);
- X
- X} /* remove() */
- X
- X/*
- X * EDIT FILE(S)
- X */
- X
- X/* Edit current or tagged file(s) */
- LOCAL int edit(one)
- X register int one;
- X{
- X char name[FILELEN];
- X register char *fname;
- X register int f, c, mode, req;
- X
- X who = "EDIT FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X if(CNTAG > 1) {
- X puthelp("%s (N:don't request Q:quit ELSE:request)", who);
- X c = hitakey("Request before edit ?", echoline, DA_NONE);
- X if(c == 'q' || c < RV_NUL)
- X return(c);
- X else if(req = (c != 'n'))
- X puthelp("%s (Y:edit Q:quit ELSE:don't edit)", who);
- X }
- X else
- X req = 1;
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X c = editfile(FFNAM(cdlist, f), (int) FMODE(cdlist, f), req);
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X else { /* Current or no files */
- X if(CNFIL > 0) {
- X setmark(CFCUR, FF_MARK);
- X puthelp("%s: Give file name (CR:%s)", who, FFNAM(cdlist, CFCUR));
- X c = putecho("Edit file:");
- X c = getline(name, sizeof(name), c, 0, NULL, GNULL, 0);
- X unsetmark(CFCUR);
- X if(c < RV_NUL)
- X return(c);
- X }
- X else { /* Directory is empty */
- X puthelp("%s: Give file name (CR:quit)", who);
- X c = putecho("Edit which file:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, GNULL, 0)) != RV_OK)
- X return(c);
- X }
- X fname = c == RV_NUL ? FFNAM(cdlist, CFCUR) : name;
- X mode = c == RV_NUL ? FMODE(cdlist, CFCUR) : FF_NONE;
- X c = editfile(fname, mode, 0);
- X }
- X
- X return(c);
- X
- X} /* edit() */
- X
- X/* Edit single file name (mode mode) with request if req is set */
- LOCAL int editfile(name, mode, req)
- X register char *name;
- X register int mode, req;
- X{
- X char pname[NAMELEN], buf[EXECLEN];
- X register int c;
- X
- X /* Check if editing is allowed */
- X if( !isallowed(name, mode))
- X return(hitakey(NULL));
- X
- X (void) strcpy(pname, pathname(name, CPNAM));
- X if(req) {
- X (void) putecho("Edit %s ?", name);
- X c = hitakey(NULL);
- X if(c != 'y')
- X return(c);
- X }
- X (void) sprintf(buf, "%s %s %s", VARVAL(V_ED), VARVAL(V_EDO), pname);
- X (void) callsystem(buf, 1, 1);
- X
- X checkdlist(CPNAM); /* Directory needs checking */
- X return(RV_OK);
- X
- X} /* editfile() */
- X
- X/*
- X * COPY FILE(S)
- X */
- X
- X/* Copy current or tagged file(s) */
- LOCAL int copy(one)
- X register int one;
- X{
- X struct stat st;
- X char name[NAMELEN];
- X register char *to;
- X register int f, c, req;
- X
- X if(CNFIL == 0) /* Nothing to copy */
- X return(RV_OK);
- X
- X who = "COPY FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X puthelp("%s: Give destination directory (CR:select one)", who);
- X c = putecho("Copy tagged files to:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, CLIST, 0)) < RV_NUL)
- X return(c);
- X if(c == RV_OK) {
- X to = strcpy(name, pathname(name, CPNAM));
- X if((*statfun)(to, &st) < 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(name, "Cannot stat"));
- X }
- X else if(STFMT(&st) != S_IFDIR) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(name, "Is not a directory"));
- X }
- X }
- X else if((to = doselect("copying files")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X puthelp("%s (N:don't request Q:quit ELSE:request)", who);
- X (void) putecho("Request before copying to %s ?", to);
- X c = hitakey(NULL);
- X if(c == 'q' || c < RV_NUL)
- X return(c);
- X if(req = (c != 'n'))
- X puthelp("%s (Y:copy Q:quit ELSE:don't copy)", who);
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X setmark(f, FF_MARK);
- X c = copyfile(cdlist, f, to, req);
- X unsetmark(f);
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X else { /* Current file */
- X puthelp("%s: Give destination (CR:select directory)", who);
- X c = putecho("Copy file to:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, CLIST, 0)) < RV_NUL)
- X return(c);
- X else if(c == RV_OK)
- X to = strcpy(name, pathname(name, CPNAM));
- X else if((to = doselect("copying file")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X c = copyfile(cdlist, CFCUR, to, 0);
- X }
- X
- X checkdlist(to); /* Directory needs checking */
- X fileflag |= SF_ECHO|SF_HELP;
- X return(c);
- X
- X} /* copy() */
- X
- X/*
- X * ZOOM FILES
- X */
- X
- X/* Get zoom pattern and rebuild filelist */
- LOCAL int zoomfile()
- X{
- X char pat[PATLEN];
- X register int c;
- X
- X who = "ZOOM FILE";
- X puthelp("%s: Give file pattern (CR:all files)", who);
- X if((c = getpattern(pat, "Zoom which files:")) < RV_NUL)
- X return(c);
- X if(zoomlist(cdlist, pat))
- X fileflag |= SF_TREE;
- X return(RV_OK);
- X
- X} /* zoomfile() */
- X
- X/*
- X * GOTO DIRECTORY / PARENT DIRECTORY
- X */
- X
- X/* Goto directory */
- LOCAL int gotodirectory()
- X{
- X#ifdef S_IFLNK
- X struct stat st;
- X#endif /* S_IFLNK */
- X register dlist *dp;
- X register int lev, c;
- X
- X if(CNFIL == 0) /* Nothing to change to */
- X return(RV_OK);
- X
- X who = "GOTO DIRECTORY";
- X puthelp("%s: %s", who, FFNAM(cdlist, CFCUR));
- X if(FMODE(cdlist, CFCUR) != FF_DIR) {
- X#ifdef S_IFLNK
- X if( !(FMODE(cdlist, CFCUR) == FF_SLNK && ISDIR(FFNAM(cdlist, CFCUR), st)))
- X#endif /* S_IFLNK */
- X return(errequest(FFNAM(cdlist, CFCUR), "Is not a directory"));
- X }
- X
- X /* Search directory in directory tree */
- X for(dp = (dlist *) CNEXT, lev = CLEVL+1; dp && DLEVL(dp) > CLEVL; dp = (dlist *) DNEXT(dp))
- X if(DLEVL(dp) == lev && EQU(FFNAM(cdlist, CFCUR), DFNAM(dp)))
- X break;
- X /* Directory is not yet in directory tree */
- X if(dp == DNULL || DLEVL(dp) != lev)
- X dp = newdlist(FFNAM(cdlist, CFCUR), FL_NUL);
- X
- X /* Directory file list must be read in */
- X if((DFLAG(dp) != FL_FIL || changedlist(dp)) && (c = newflist(dp)) != RV_OK)
- X return(c);
- X
- X if( !DCANC(dp))
- X return(errequest(DFNAM(dp), "Cannot change"));
- X else if(DNFIL(dp) == 0) {
- X puthelp("%s: %s (y:change ELSE:don't change)", who, DFNAM(dp));
- X c = errequest(DFNAM(dp), "Is empty, change anyway ?");
- X if(c != 'y')
- X return(c);
- X }
- X
- X /* Position to directory in directory tree and return */
- X while(cdlist != dp)
- X (void) gotree(1);
- X
- X return(RV_DIR);
- X
- X} /* gotodirectory() */
- X
- X/* Goto parent directory */
- LOCAL int gotoparent()
- X{
- X register char *name;
- X register int lev, c;
- X
- X if(cdlist == droot) /* Root has no parent */
- X return(RV_RET);
- X
- X /* Position to parent directory in directory tree */
- X name = CFNAM;
- X lev = CLEVL - 1;
- X while(CLEVL != lev)
- X (void) gotree(-1);
- X /* Parent directory needs rebuilding */
- X if((CFLAG != FL_FIL || changedlist(cdlist))
- X && (c = newflist(cdlist)) != RV_OK)
- X return(c);
- X /* Position to where we came from in parent directory file list */
- X CFCUR = CFTOP = 0;
- X while(CMP(name, FFNAM(cdlist, CFCUR)) && CFCUR < CNFIL)
- X (void) gofile(cdlist, 1);
- X
- X return(RV_DIR);
- X
- X} /* gotoparent() */
- X
- X/*
- X * TAG / UNTAG FILE(S)
- X */
- X
- X/* Tag current or selected file(s) */
- LOCAL int tag(one)
- X register int one;
- X{
- X char input[PATLEN];
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to tag */
- X return(RV_OK);
- X
- X who = "TAG FILE";
- X if( !one) { /* Multiple files */
- X puthelp("%s: Give file pattern (CR:%s)", who, tpattern[0] ? tpattern : "quit");
- X if((c = getpattern(input, "Tag which file:")) == RV_OK)
- X (void) strcpy(tpattern, input);
- X else if(c < RV_NUL || (c == RV_NUL && tpattern[0] == '\0'))
- X return(c);
- X }
- X if(one) /* Currrent file */
- X tagfile(CFCUR);
- X else /* Matching files */
- X for(f = 0; f < CNFIL; f++)
- X if(umatch(cdlist, f, tpattern) > 0)
- X tagfile(f);
- X
- X return(RV_OK);
- X
- X} /* tag() */
- X
- X/* Untag current or selected file(s) */
- LOCAL int untag(one)
- X register int one;
- X{
- X char pattern[PATLEN];
- X register int f, c;
- X
- X if(CNFIL == 0) /* Nothing to untag */
- X return(RV_OK);
- X
- X who = "UNTAG FILE";
- X if( !one) { /* Multiple files */
- X setmark(CFCUR, FF_MARK);
- X puthelp("%s: Give file pattern (CR:all files)", who);
- X c = getpattern(pattern, "Untag which file:");
- X unsetmark(CFCUR);
- X if(c < RV_NUL)
- X return(c);
- X else if(c == RV_NUL)
- X (void) strcpy(pattern, "*");
- X }
- X if(one && ISTAG(cdlist, CFCUR)) { /* Current file */
- X untagfile(CFCUR);
- X unsetmark(CFCUR);
- X }
- X else /* Matching files */
- X for(f = 0; f < CNFIL; f++)
- X if(umatch(cdlist, f, pattern) > 0 && ISTAG(cdlist, f)) {
- X untagfile(f);
- X unsetmark(f);
- X }
- X
- X return(RV_OK);
- X
- X} /* untag() */
- X
- X/*
- X * EXECUTE CURRENT FILE
- X */
- X
- X/* Check if current file is given in command */
- LOCAL int filemissing(s)
- X register char *s;
- X{
- X while(*s) {
- X if(*s == '%') { /* Leadin found */
- X ++s;
- X if(*s == 'f' || *s == 'F' || *s == 'p' || *s == 'P')
- X return(0); /* Found */
- X }
- X else
- X ++s;
- X }
- X return(1);
- X
- X} /* filemissing() */
- X
- X/* Execute or execute on file f */
- LOCAL int execfile(f, m)
- X register int f, m;
- X{
- X char cmd[EXECLEN], buf[2*INPLEN], par[INPLEN];
- X register xlist *xp;
- X register int c;
- X
- X if(m)
- X setmark(f, FF_MARK);
- X /* Check if a command is defined for filetype */
- X for(xp = xroot; xp; xp = (xlist *) XNEXT(xp))
- X if(umatch(cdlist, f, XTYPE(xp)))
- X break;
- X
- X /* Execute filetype dependent command if defined */
- X if(xp && XCOMD(xp)) {
- X if(XCOMM(xp))
- X puthelp("%s: %s #%s", who, FFNAM(cdlist, f), XCOMM(xp));
- X else
- X puthelp("%s: %s", who, FFNAM(cdlist, f));
- X c = putecho("Execute:");
- X c = getline(buf, sizeof(buf), c, 'l', XCOMD(xp), GNULL, 0);
- X if(m)
- X unsetmark(f);
- X if(c != RV_OK)
- X return(c);
- X if(filemissing(buf))
- X (void) sprintf(buf, "%s %%F", buf);
- X }
- X /* File is executable */
- X else if(FMODE(cdlist, f) == FF_EXEC) {
- X puthelp("%s: Give parameter(s) or a command", who);
- X c = putecho("Execute %s:", FFNAM(cdlist, f));
- X c = getline(par, sizeof(par), c, 'l', NULL, GNULL, 0);
- X if(m)
- X unsetmark(f);
- X if(c < RV_NUL)
- X return(c);
- X else if(c == RV_NUL)
- X (void) strcpy(buf, "./%F");
- X else if(filemissing(par))
- X (void) sprintf(buf, "%%F %s", par);
- X else
- X (void) strcpy(buf, par);
- X }
- X /* Execute command on current file */
- X else {
- X puthelp("%s: Give a command and parameter(s)", who);
- X c = putecho("Execute on %s:", FFNAM(cdlist, f));
- X c = getline(par, sizeof(par), c, 'l', NULL, GNULL, 0);
- X if(m)
- X unsetmark(f);
- X if(c != RV_OK)
- X return(c);
- X if(filemissing(par))
- X (void) sprintf(buf, "%s %%F", par);
- X else
- X (void) strcpy(buf, par);
- X }
- X
- X /* Format command line and execute */
- X c = userformat(cmd, buf, V_FC1, "EXECUTE");
- X if(c == RV_NUL) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(FFNAM(cdlist, f), "Bad format"));
- X }
- X else if(c < RV_NUL)
- X return(c);
- X
- X puthelp("%s: %s", who, cmd);
- X c = callsystem(cmd, 1, 0);
- X
- X if(c != RV_OK) {
- X puthelp("%s: %s %s", who, cmd, hitkey);
- X return(errequest(FFNAM(cdlist, f), "Error in executing"));
- X }
- X return(hitakey("Return from execute (Hit a key)", lines-1, DA_REVERSE));
- X
- X} /* execfile() */
- X
- X/* Execute or execute on files */
- LOCAL int execute(one)
- X register int one;
- X{
- X register int c, f, m;
- X
- X if(CNFIL == 0) /* Nothing to execute */
- X return(RV_OK);
- X
- X who = "EXECUTE FILE";
- X if( !one && CNTAG) { /* Tagged files */
- X m = 1;
- X for(f = 0; f < CNFIL; f++)
- X if(ISTAG(cdlist, f)) {
- X untagfile(f);
- X c = execfile(f, m);
- X m = 0;
- X if(c == 'q' || c < RV_NUL)
- X break;
- X }
- X }
- X else /* Current file */
- X c = execfile(CFCUR, 1);
- X
- X checkdlist(CPNAM); /* Directory needs checking */
- X return(c);
- X
- X} /* execute() */
- X
- X/*
- X * FILE MENU LOOP
- X */
- X
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X/* Refresh file screen after screen size changes */
- GLOBL int refreshfile(f)
- X register int f;
- X{
- X if(f)
- X (void) refreshtree(0);
- X f = CFCUR;
- X CFTOP = CFCUR = 0;
- X while(CFCUR != f && gofile(cdlist, 1))
- X ;
- X flast = -1;
- X fileflag = SF_FULL;
- X return(RV_OK);
- X
- X} /* refreshfile() */
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X
- X/* File menu */
- GLOBL int filemenu(f, r)
- X register int f, r;
- X{
- X register int c, i, j;
- X
- X who = "FILE MENU";
- X /* Change to directory and check if it is empty */
- X if((c = changelist(cdlist, who)) != RV_OK)
- X return(c);
- X else if(r != RV_DIR && CNFIL == 0) {
- X puthelp("%s: %s (Y:change ELSE:don't change)", who, CFNAM);
- X if((c = errequest(CFNAM, "Is empty, change anyway ?")) != 'y')
- X return(c);
- X }
- X
- X /* Position to current file on screen */
- X if(f >= 0 && f < CNFIL)
- X while(CFCUR != f)
- X (void) gofile(cdlist, CFCUR < f ? 1 : -1);
- X
- X /* Init file variables */
- X if(menuline == NULL)
- X menuline = fmline;
- X buildflag = 0;
- X nscroll = 0;
- X flast = -1;
- X fmark = -1;
- X fileflag = SF_FULL;
- X
- X /* File menu loop */
- X do {
- X /* Update file screen if needed and clock */
- X if(fileflag && !keypressed())
- X updatefiles();
- X#ifdef UTCLOCK
- X if(VARSET(V_CL))
- X clockon();
- X#endif /* UTCLOCK */
- X flushout();
- X c = getkey();
- X#ifdef UTCLOCK
- X if(VARSET(V_CL))
- X clockoff();
- X#endif /* UTCLOCK */
- X switch(c) {
- X default: /* Unknown: ring the bell */
- X bell(VARSET(V_BL));
- X break;
- X case K_BACK: /* Previous file */
- X case 'k': /* For vi fans */
- X if( !gofile(cdlist, -1))
- X bell(VARSET(V_BL));
- X break;
- X case K_FORW: /* Next file */
- X case 'j': /* For vi fans */
- X if( !gofile(cdlist, 1))
- X bell(VARSET(V_BL));
- X break;
- X case K_PREV: /* Up file */
- X if(gofile(cdlist, -1))
- X for(i = 1; i < fperline; i++)
- X (void) gofile(cdlist, -1);
- X else
- X bell(VARSET(V_BL));
- X break;
- X case K_NEXT: /* Down file */
- X if(gofile(cdlist, 1))
- X for(i = 1; i < fperline; i++)
- X (void) gofile(cdlist, 1);
- X else
- X bell(VARSET(V_BL));
- X break;
- X case K_PPAG: /* Previous page */
- X if(CFTOP > 0 && gofile(cdlist, -1))
- X for(i = 1; i < fperpage && gofile(cdlist, -1); i++)
- X ;
- X else
- X bell(VARSET(V_BL));
- X break;
- X case K_NPAG: /* Next page */
- X if((CFTOP + fperpage) < CNFIL && gofile(cdlist, 1))
- X for(i = 1; i < fperpage && gofile(cdlist, 1); i++)
- X ;
- X else
- X bell(VARSET(V_BL));
- X break;
- X case K_HOME: /* First file */
- X i = CFCUR;
- X if(gofile(cdlist, -1)) {
- X fmark = i;
- X while(gofile(cdlist, -1))
- X ;
- X }
- X else
- X bell(VARSET(V_BL));
- X break;
- X case K_END: /* Last file */
- X i = CFCUR;
- X if(gofile(cdlist, 1)) {
- X fmark = i;
- X while(gofile(cdlist, 1))
- X ;
- X }
- X else
- X bell(VARSET(V_BL));
- X break;
- X case '@': /* Mark current file */
- X case K_MARK:
- X fmark = CFCUR;
- X break;
- X case '#': /* Goto previously marked file */
- X case K_GOTO:
- X j = fmark;
- X for(i = CFCUR; i < CNFIL; i++)
- X if(fmark == i) {
- X while(gofile(cdlist, 1) && CFCUR != fmark)
- X ;
- X fmark = j;
- X goto MDONE;
- X }
- X for(i = 0; i < CFCUR; i++)
- X if(fmark == i) {
- X while(gofile(cdlist, -1) && CFCUR != fmark)
- X ;
- X fmark = j;
- X goto MDONE;
- X }
- X bell(VARSET(V_BL));
- MDONE: break;
- X case K_TAG: /* Next tagged file */
- X for(i = CFCUR + 1; i < CNFIL; i++)
- X if(ISTAG(cdlist, i)) {
- X while(gofile(cdlist, 1) && CFCUR != i)
- X ;
- X goto TDONE;
- X }
- X for(i = 0; i < CFCUR; i++)
- X if(ISTAG(cdlist, i)) {
- X while(gofile(cdlist, -1) && CFCUR != i)
- X ;
- X goto TDONE;
- X }
- X bell(VARSET(V_BL));
- TDONE: break;
- X case K_UP: /* Scroll up */
- X if( !scrollfile(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_DOWN: /* Scroll down */
- X if( !scrollfile(1))
- X bell(VARSET(V_BL));
- X break;
- X case '>': /* Change to directory */
- X case K_INS:
- X c = gotodirectory();
- X break;
- X case '<': /* Back to parent directory */
- X case K_DEL:
- X c = gotoparent();
- X break;
- X case K_SIZE: /* Screen size changed */
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X c = RV_SIZ;
- X#else /* !SIGWINCH || !TIOCGWINSZ */
- X c = RV_OK;
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X /*Fall thru*/
- X case K_REFR: /* Refresh */
- X fileflag = SF_FULL;
- X break;
- X case 'n': /* New sort file list */
- X case 'N':
- X fmark = -1;
- X if((c = sortlist(cdlist, CSORT ? 0 : 1)) == RV_OK)
- X fileflag |= SF_TREE;
- X break;
- X case 'd': /* Date */
- X case 'D':
- X c = printdate();
- X break;
- X case 'w': /* Current directory */
- X case 'W':
- X c = printcwd();
- X break;
- X case '?': /* Help */
- X case 'H':
- X case 'h':
- X case K_HELP:
- X c = showhelp('f');
- X break;
- X case 't': /* Tag current or tagged file(s) */
- X case 'T':
- X c = tag(CUR(c));
- X break;
- X case 'u': /* Untag current or tagged file(s) */
- X case 'U':
- X c = untag(CUR(c));
- X break;
- X case 'g': /* Search string in file */
- X case 'G':
- X c = grep(CUR(c));
- X break;
- X case 'f': /* Find file */
- X case 'F':
- X c = find(CUR(c));
- X break;
- X case 'c': /* Copy current or tagged file(s) */
- X case 'C':
- X c = copy(CUR(c));
- X break;
- X case 'e': /* Edit current or tagged file(s) */
- X case 'E':
- X c = edit(CUR(c));
- X break;
- X case 's': /* Status of current or tagged file(s) */
- X case 'S':
- X c = status(CUR(c), 1);
- X break;
- X case 'i': /* Short info of current or tagged file(s) */
- X case 'I':
- X c = status(CUR(c), 0);
- X break;
- X case 'p': /* Print current or tagged file(s) */
- X case 'P':
- X c = print(CUR(c));
- X break;
- X case 'v': /* View current or tagged file(s) */
- X case 'V':
- X c = view(CUR(c));
- X break;
- X case 'm': /* Move current or tagged file(s) */
- X case 'M':
- X c = move(CUR(c));
- X break;
- X case 'r': /* Remove current or tagged file(s) */
- X case 'R':
- X c = remove(CUR(c));
- X break;
- X case 'l': /* List files */
- X case 'L':
- X c = list(CUR(c));
- X break;
- X case 'x': /* Execute current file */
- X case 'X':
- X c = execute(CUR(c));
- X break;
- X case '0': /* Switch menu line */
- X menuline = menuline == ufilemenu ? fmline : ufilemenu;
- X fileflag |= SF_HELP;
- X break;
- X case '1': /* User defined file commands 1..9 */
- X case '2':
- X case '3':
- X case '4':
- X case '5':
- X case '6':
- X case '7':
- X case '8':
- X case '9':
- X c = usercommand(c - '0' + V_FC0);
- X break;
- X case '!': /* Shell escape */
- X case '$':
- X c = history(c, V_FC1);
- X if(VARSET(V_ST))
- X (void) scandlist(droot);
- X break;
- X case '=': /* Show/set variables */
- X c = variables();
- X break;
- X case ':': /* Show/set file type commands */
- X c = commands();
- X break;
- X case '|': /* Show key bindings */
- X c = bindings();
- X break;
- X case '/': /* Rebuild file list */
- X fmark = -1;
- X CFLAG = FL_CHG;
- X ++buildflag;
- X c = RV_OK;
- X break;
- X case 'z': /* Zoom file list */
- X case 'Z':
- X c = zoomfile();
- X break;
- X case 'a': /* Display version string */
- X case 'A':
- X c = putversion(echoline, "ABOUT: Utree version");
- X break;
- X case 'q': /* Return to tree screen */
- X case 'Q':
- X case ' ':
- X case K_SEL:
- X case K_BRK:
- X c = RV_RET;
- X break;
- X case K_EOF: /* Exit */
- X c = RV_END;
- X break;
- X }
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X /* Refresh screen after screen resize */
- X if(c == RV_SIZ)
- X c = refreshfile(1);
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X /* Rebuilding needed */
- X if(buildflag && updatedlist() != RV_OK)
- X c = RV_ERR;
- X } while(c >= RV_INT);
- X
- X /* Set treeflag and return */
- X treeflag = SF_FULL;
- X return(c);
- X
- X} /* filemenu() */
- X
- END_OF_FILE
- if test 41484 -ne `wc -c <'src/file.c'`; then
- echo shar: \"'src/file.c'\" unpacked with wrong size!
- fi
- # end of 'src/file.c'
- fi
- if test -f 'src/term.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/term.c'\"
- else
- echo shar: Extracting \"'src/term.c'\" \(30770 characters\)
- sed "s/^X//" >'src/term.c' <<'END_OF_FILE'
- X/*
- X * TERM.C
- X * UTREE terminal, screen and keyboard routines.
- X * 3.01-um klin, Wed May 1 14:21:09 1991
- X * klin, Mon Oct 7 15:16:22 1991, Bug in putchar() deleted
- X * klin, Sat Oct 26 15:26:07 1991, Marking directories changed
- X * 3.02-um klin, Fri Nov 1 10:44:45 1991, Screen layout changed
- X * Sun Nov 10 19:46:21 1991, Function key handling changed
- X * Sun Nov 24 12:22:56 1991, Extensions for XENIX reported
- X * by Rolf Gebhardt (RG 11/22/91)
- X * Bug fixes in output reported by
- X * Reinhard Wobst and Rolf Gebhardt
- X * Video attributes changed
- X * 3.03-um klin, Tue Feb 11 19:39:09 1992, Video handling changed
- X * Handle glitch capabilities
- X * properly
- X * klin, Sun Feb 23 20:33:30 1992, Key handling and key bindings
- X * changed. getkey() changed for
- X * handling key bindings from
- X * key bindings list
- X * a klin, Sun Mar 15 19:08:25 1992, Bug fix in getkey(), clearline()
- X * and cleartoend().
- X * Minor changes for AIX 3.2
- X *
- X * Copyright (c) 1991/92 by Peter Klingebiel & UNIX Magazin Muenchen.
- X * For copying and distribution information see the file COPYRIGHT.
- X */
- X#ifndef lint
- static char sccsid[] = "@(#) utree 3.03a-um (klin) Mrz 15 1992 term.c";
- X#endif /* !lint */
- X
- X#include "defs.h"
- X
- X/* TEST: Handling of sg/ug glitches (i.e. for bando terminal)
- X * Handling of sg/ug glitches may be wrong because i could test
- X * their handling on xterm simulating the sg/ug glitches only.
- X */
- X
- X/* ---- Local/global variables and definitions ------------------------ */
- X
- X#define TCAPLEN 1024 /* Length of termcap buffers */
- X#define KBUFLEN 254 /* Length of keyboard buffer */
- X#define HUGE 9999 /* A huge number */
- X
- GLOBL char PC; /* Needed by termcap (???) */
- GLOBL char *UP; /* Needed by termcap (???) */
- GLOBL char *BC; /* Needed by termcap (???) */
- X
- LOCAL int _XR; /* Carriage return glitch */
- LOCAL int _MS; /* Can move cursor in standout mode */
- LOCAL int _SG; /* Standout mode glitch: # of blanks */
- LOCAL int _UG; /* Underline glitch: # of blanks */
- LOCAL char *_CM; /* Cursor motion */
- LOCAL char *_CL; /* Clear screen */
- LOCAL char *_CD; /* Clear to end of screen */
- LOCAL char *_CE; /* Clear to end of line */
- LOCAL char *_TI; /* Init string for cursor motion */
- LOCAL char *_TE; /* Exit string for cursor motion */
- LOCAL char *_KS; /* Turn on keypad transmit mode */
- LOCAL char *_KE; /* Turn off keypad transmit mode */
- LOCAL char *_MR; /* Turn on reverse video mode */
- LOCAL char *_MB; /* Turn on blink video mode */
- LOCAL char *_MD; /* Turn on bold video mode */
- LOCAL char *_MH; /* Turn on half bright video mode */
- LOCAL char *_ME; /* Turn off all video attributes */
- LOCAL char *_US; /* Start underlining */
- LOCAL char *_UE; /* End underlining */
- LOCAL char *_IC; /* Insert character at cursor position */
- LOCAL char *_DC; /* Delete character at cursor position */
- LOCAL char *_AL; /* Insert line above line cursor is on */
- LOCAL char *_DL; /* Delete line cursor is on */
- LOCAL char *_CS; /* Set scroll region */
- LOCAL char *_NL; /* New line (default: ^J = NL) */
- LOCAL char *_CR; /* Carriage return (default: ^M = CR) */
- LOCAL char *_LE; /* Cursor left (default: ^H = BS) */
- LOCAL char *_DO; /* Cursor down */
- LOCAL char *_SF; /* Scroll screen up */
- LOCAL char *_SR; /* Scroll screen down */
- LOCAL char *_SC; /* Save cursor position */
- LOCAL char *_RC; /* Restore cursor position */
- LOCAL char *_VE; /* Cursor normal */
- LOCAL char *_VS; /* Cursor very visible */
- LOCAL char *_VI; /* Cursor invisible */
- LOCAL char *_BL; /* Bell (default ^G = BEL) */
- LOCAL char *_AC = NULL; /* Alternate character set */
- LOCAL char *_EA = NULL; /* Enable alternate character set */
- LOCAL char *_AS = NULL; /* Alternate character set on */
- LOCAL char *_AE = NULL; /* Alternate character set off */
- X#ifdef XENIX /* RG 11/22/91 */
- LOCAL char *_G2 = NULL; /* Upper left corner */
- LOCAL char *_GH = NULL; /* Horizontal bar */
- LOCAL char *_G1 = NULL; /* Upper right corner */
- LOCAL char *_GV = NULL; /* Vertical bar */
- LOCAL char *_G4 = NULL; /* Lower right corner */
- LOCAL char *_G3 = NULL; /* Lower left corner */
- LOCAL char *_GD = NULL; /* Top tee */
- LOCAL char *_GL = NULL; /* Right tee */
- LOCAL char *_GU = NULL; /* Bottom tee */
- LOCAL char *_GR = NULL; /* Left tee */
- LOCAL char *_GC = NULL; /* Plus sign = mark sign */
- X#endif /* XENIX */
- X
- LOCAL char termbuf[TCAPLEN]; /* Termcap buffer */
- LOCAL int nfkeys; /* Number of defined function keys */
- X#ifdef BSD
- LOCAL struct sgttyb raw, tty; /* Terminal driver data record */
- X# define TCGETA TIOCGETP
- X# define TCSETA TIOCSETP
- X#else /* SYSV */
- LOCAL struct termio raw, tty;
- X# ifndef HASFIONREAD
- LOCAL int kbflag; /* Input mode flag */
- X# endif /* !HASFIONREAD */
- X#endif /* BSD */
- X
- LOCAL kchar kbuf[KBUFLEN+2]; /* Input buffer */
- LOCAL int kcnt = 0; /* Input buffer counter */
- LOCAL int kind = 0; /* Input buffer index */
- LOCAL int curx = HUGE; /* Current screen column */
- LOCAL int cury = HUGE; /* Current screen line */
- LOCAL int vatt = VA_NORMAL; /* Current video attributes setting */
- LOCAL int gatt = GC_OFF; /* Current graphic character set flag */
- X
- X/* ---- External variables and functions ------------------------------ */
- X
- X#ifdef BSD
- XEXTRN short ospeed; /* Is ospeed really needed??? */
- X#endif /* BSD */
- XEXTRN char *getenv();
- XEXTRN char *tgetstr();
- XEXTRN char *tgoto();
- X
- X/* ---- Local/global functions and procedures ------------------------- */
- X
- X/*
- X * INTERNAL USED ROUTINES
- X */
- X
- X/* Output one character for tputs() */
- LOCAL int _putch(c)
- X register int c;
- X{
- X return(putc((unsigned char) c, stdout));
- X
- X} /* _putch() */
- X
- X/*TEST: Handling of sg/ug glitches */
- X/* Move cursor back for terminals with underline or standout glitch */
- LOCAL VOID _backglitch(j)
- X register int j;
- X{
- X register int i;
- X
- X for(i = 0; i < j; i++) {
- X if(_LE)
- X tputs(_LE, 1, _putch);
- X else if(BC)
- X tputs(BC, 1, _putch);
- X else
- X (void) _putch('\b');
- X }
- X
- X} /* _backglitch() */
- X
- X/*
- X * VIDEO ATTRIBUTE AND GRAPHIC CHARSET ROUTINES
- X */
- X
- X/* Turn on/off video attributes as defined in mask v */
- GLOBL VOID videoset(v)
- X register int v;
- X{
- X if(vatt) { /* Video attributes off */
- X if((vatt & VA_UNDERLINE) && _UE) {
- X tputs(_UE, 1, _putch);
- X/*TEST: Handling of sg/ug glitches */
- X if(_UG > 0)
- X _backglitch(_UG);
- X vatt &= ~VA_UNDERLINE;
- X }
- X if(vatt && _ME) {
- X tputs(_ME, 1, _putch);
- X/*TEST: Handling of sg/ug glitches */
- X if(_SG > 0)
- X _backglitch(_SG);
- X }
- X }
- X vatt = VA_NORMAL;
- X if(v & VA_REVERSE && _MR) { /* Video reverse */
- X tputs(_MR, 1, _putch);
- X/*TEST: Handling of sg/ug glitches */
- X if(_SG > 0)
- X _backglitch(_SG);
- X vatt |= VA_REVERSE;
- X }
- X if(v & VA_UNDERLINE && _US) { /* Start underlining */
- X tputs(_US, 1, _putch);
- X/*TEST: Handling of sg/ug glitches */
- X if(_UG > 0)
- X _backglitch(_UG);
- X vatt |= VA_UNDERLINE;
- X }
- X if(v & VA_BLINK && _MB) { /* Video blink */
- X tputs(_MB, 1, _putch);
- X vatt |= VA_BLINK;
- X }
- X if(v & VA_BOLD && _MD) { /* Video bold */
- X tputs(_MD, 1, _putch);
- X vatt |= VA_BOLD;
- X }
- X if(v & VA_HALF && _MH) { /* Video half bright */
- X tputs(_MH, 1, _putch);
- X vatt |= VA_HALF;
- X }
- X
- X} /* videoset() */
- X
- X/* Turn on/off graphic character set as defined in flag f */
- GLOBL VOID graphicset(f)
- X register int f;
- X{
- X if(gatt != f) {
- X if(f && _AS) /* Enable graphic charset */
- X tputs(_AS, 1, _putch);
- X else if(_AE) /* Disable graphic charset */
- X tputs(_AE, 1, _putch);
- X gatt = f;
- X }
- X
- X} /* graphicset() */
- X
- X/*
- X * OUTPUT ROUTINES
- X */
- X
- X/* Ring the bell */
- GLOBL VOID bell(f)
- X register int f;
- X{
- X if(f) {
- X if(_BL)
- X tputs(_BL, 1, _putch);
- X else
- X (void) _putch(7);
- X }
- X
- X} /* bell() */
- X
- X/* Move cursor back one character */
- GLOBL VOID backspace()
- X{
- X if(curx > 0) {
- X if(_LE)
- X tputs(_LE, 1, _putch);
- X else if(BC)
- X tputs(BC, 1, _putch);
- X else
- X (void) _putch('\b');
- X --curx;
- X }
- X
- X} /* backspace() */
- X
- X/* Move to beginning of line */
- GLOBL VOID begline()
- X{
- X if(curx > 0) {
- X curx = 0;
- X if(_XR)
- X (void) cursorxy(0, cury);
- X else if(_CR)
- X tputs(_CR, 1, _putch);
- X else
- X (void) _putch('\r');
- X }
- X
- X} /* begline() */
- X
- X/* Move to beginning of next line */
- GLOBL VOID newline()
- X{
- X if(cury < lines) {
- X begline();
- X ++cury;
- X if(_NL)
- X tputs(_NL, 1, _putch);
- X else if(_DO)
- X tputs(_DO, 1, _putch);
- X else
- X (void) _putch('\n');
- X }
- X
- X} /* newline() */
- X
- X/* Write character c if cursor is on screen */
- GLOBL int putchar(c)
- X register int c;
- X{
- X if(videoattr != vatt) /* Check and set video attributes */
- X videoset(videoattr);
- X if(graphattr != gatt) /* Check and set graphic charset */
- X graphicset(graphattr);
- X switch(c) {
- X case 7: /* Bell */
- X bell(1);
- X break;
- X case '\b': /* Backspace */
- X backspace();
- X break;
- X case '\t': /* Tab */
- X if(curx < columns && cury < lines) {
- X do
- X (void) _putch(' ');
- X while(++curx % 8 && curx < columns);
- X }
- X break;
- X case '\n': /* Newline */
- X newline();
- X break;
- X case '\r': /* Carriage return */
- X begline();
- X break;
- X default: /* Others */
- X if(curx < columns && cury < lines && isprint(c & 0x7f)) {
- X (void) _putch(c);
- X ++curx;
- X }
- X break;
- X }
- X return(curx < columns && cury < lines ? 1 : 0);
- X
- X} /* putchar() */
- X
- X/* Flush output buffer */
- GLOBL VOID flushout()
- X{
- X (void) fflush(stdout);
- X
- X} /* flushout() */
- X
- X/*
- X * INPUT ROUTINES
- X */
- X
- X/* Read one character from keyboard. Ignore or handle signals */
- GLOBL int getchar()
- X{
- X register int c;
- X
- X#ifdef BSD
- X atread = 1;
- X# if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X /* BSD: Signal SIGWINCH doesn't interrupt systemcall read() ! */
- X /* Set up here if SIGWINCH is catched and return K_SIZE */
- X if(setjmp(winchjump) && sizechange) {
- X sizechange = atread = 0;
- X return(K_SIZE);
- X }
- X# endif /* SIGWINCH && TIOCGWINSZ */
- X c = getc(stdin);
- X atread = 0;
- X return(c);
- X#else /* SYSV */
- X do {
- X c = getc(stdin);
- X# if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X /* SYSV: Signal SIGWINCH interrupts systemcall read() ! */
- X /* So return K_SIZE if signal SIGWINCH is catched */
- X if(c < 0 && sizechange) {
- X sizechange = 0;
- X return(K_SIZE);
- X }
- X# endif /* SIGWINCH && TIOCGWINSZ */
- X }
- X while(c < 0 && errno == EINTR);
- X return(c);
- X#endif /* BSD */
- X
- X} /* getchar() */
- X
- X/* Check if input from keyboard is pending */
- GLOBL int keypressed()
- X{
- X int c;
- X
- X#if defined(BSD) || defined(HASFIONREAD)
- X /* Quick check how many chars are to read */
- X return(ioctl(fileno(stdin), FIONREAD, &c) < 0 ? 0 : c);
- X#else /* SYSV && !HASFIONREAD */
- X /* Set stdin to no delay and try to read one char */
- X (void) fcntl(fileno(stdin), F_SETFL, kbflag|O_NDELAY);
- X c = getc(stdin);
- X (void) fcntl(fileno(stdin), F_SETFL, kbflag);
- X if(c >= 0) {
- X (void) ungetc(c, stdin);
- X return(1);
- X }
- X return(0);
- X#endif /* BSD || HASFIONREAD */
- X
- X} /* keypressed() */
- X
- X/* Read a character from keyboard with respect to function keys */
- GLOBL int getkey()
- X{
- X register klist *fp, *lp, *p;
- X register kchar c;
- X register int k;
- X
- X /* Flush output buffer */
- X flushout();
- X
- X /* Input buffer contains character(s) */
- X if(kcnt > 0) {
- X --kcnt;
- X return((int) kbuf[kind++]);
- X }
- X
- X /* Get next character */
- X if((c = getchar()) == 0) /* Map ASCII-NUL */
- X c = 0200;
- X /* Search for first matching entry in key binding list */
- X for(fp = kroot; fp; fp = (klist *) KBNXT(fp))
- X if(KBCHR(fp, 0) == c)
- X break;
- X /* No match: return character */
- X if(fp == KNULL)
- X return((int) c);
- X
- X /* Search for last matching entry in key binding list */
- X lp = fp;
- X while((p = (klist *) KBNXT(lp)) && KBCHR(p, 0) == c)
- X lp = p;
- X
- X /* Continue comparison of input and key strings */
- X for(k = 1; ; k++) {
- X /* Match: return bound key symbol */
- X if(fp == lp && KBCHR(fp, k) == 0) {
- X kcnt = 0;
- X if(KBSYM(fp) == K_STR && KBINS(fp)) {
- X kind = 0;
- X (void) ungetstring(KBINS(fp));
- X break;
- X }
- X return(KBSYM(fp));
- X }
- X /* Else: get next character */
- X if((c = getchar()) == 0) /* Map ASCII-NUL */
- X c = 0200;
- X kbuf[kcnt++] = c;
- X /* Search for next first and last matching entries in binding list */
- X while(KBCHR(fp, k) != c && fp != lp)
- X fp = (klist *) KBNXT(fp);
- X while(KBCHR(lp, k) != c && lp != fp)
- X lp = (klist *) KBPRV(lp);
- X /* No match: exit loop */
- X if(KBCHR(fp, k) != c)
- X break;
- X }
- X
- X /* No match: return character from input buffer */
- X --kcnt;
- X return((int) kbuf[kind++]);
- X
- X} /* getkey() */
- X
- X/* Put back character c into input buffer */
- GLOBL VOID ungetkey(c)
- X register int c;
- X{
- X if(kcnt < KBUFLEN)
- X kbuf[kcnt++] = (kchar) c;
- X
- X} /* ungetkey() */
- X
- X/* Put back string s into input buffer */
- GLOBL int ungetstring(s)
- X register char *s;
- X{
- X register int c;
- X
- X while(*s) {
- X if(*s == '\\')
- X switch(*++s) {
- X default: /* Error */
- X return(1);
- X case 'b': /* Backspace ?? */
- X c = '\b';
- X break;
- X case 'f': /* Formfeed ?? */
- X c = '\f';
- X break;
- X case 'r': /* Carriage return */
- X case 'n': /* Newline */
- X c = '\n';
- X break;
- X case 't': /* Tab */
- X c = '\t';
- X break;
- X case 's': /* Space */
- X c = ' ';
- X break;
- X case 'e': /* Escape */
- X case 'E':
- X c = 0x1b;
- X break;
- X }
- X else if(*s == '^') { /* Control chars ?? */
- X ++s;
- X if(*s == '?') /* DEL */
- X c = 0x7f;
- X else if(*s >= '@' && *s <= '_') /* NUL .. US */
- X c = *s - '@';
- X else if(*s >= 'a' && *s <= 'z') /* SOH .. SUB */
- X c = *s - '`';
- X else
- X return(1);
- X }
- X else
- X c = *s;
- X ungetkey(c);
- X ++s;
- X }
- X return(0);
- X
- X} /* ungetstring() */
- X
- X/*
- X * GLOBAL SCREEN ROUTINES
- X */
- X
- X/* Move the cursor to new x,y position */
- GLOBL int cursorxy(x, y)
- X register int x, y;
- X{
- X if(x < 0) x = columns + x;
- X if(y < 0) y = lines + y;
- X if(x < 0 || x >= columns || y < 0 || y >= lines) {
- X curx = cury = HUGE;
- X return(0);
- X }
- X if( !_MS && vatt) /* Reset video attributes */
- X videoset(VA_NORMAL);
- X if(gatt) /* Reset graphic charset */
- X graphicset(GC_OFF);
- X tputs(tgoto(_CM, x, y), 1, _putch);
- X curx = x;
- X cury = y;
- X return(1);
- X
- X} /* cursorxy() */
- X
- X/* Return current cursor position */
- GLOBL VOID cursorpos(x, y)
- X register int *x, *y;
- X{
- X *x = curx;
- X *y = cury;
- X
- X} /* cursorpos() */
- X
- X/* Insert character at cursor position */
- GLOBL int insertchar()
- X{
- X if(_IC) {
- X tputs(_IC, 1, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* insertchar() */
- X
- X/* Delete character under cursor */
- GLOBL int deletechar()
- X{
- X if(_DC) {
- X tputs(_DC, 1, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* deletechar() */
- X
- X/* Insert n lines above line cursor is on */
- GLOBL int insertline(y, n)
- X register int y, n;
- X{
- X if(_AL && cursorxy(0, y)) {
- X while(n--)
- X tputs(_AL, 1, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* insertline() */
- X
- X/* Delete n lines cursor is on */
- GLOBL int deleteline(y, n)
- X register int y, n;
- X{
- X if(_DL && cursorxy(0, y)) {
- X while(n--)
- X tputs(_DL, 1, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* deleteline() */
- X
- X/* Set scroll window from line f to line t */
- GLOBL int windowset(f, t)
- X register int f, t;
- X{
- X /* Set scroll region from line f to line t */
- X if(_CS && f <= t) {
- X tputs(tgoto(_CS, t, f), t - f + 1, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* windowset() */
- X
- X/* Scroll n lines up window from line f to line t */
- GLOBL int windowup(f, t, n)
- X register int f, t, n;
- X{
- X /* Set scrollregion from f to t and scroll up n lines */
- X if(_SF && windowset(f, t)) {
- X (void) cursorxy(0, t);
- X while(n-- > 0)
- X tputs(_SF, lines, _putch);
- X /* Reset scroll region to screen */
- X (void) windowset(0, lines - 1);
- X return(1);
- X }
- X /* Scroll up with a combination of insert and delete line */
- X else if(_AL && deleteline(f, n)) {
- X (void) insertline(t - n + 1, n);
- X return(1);
- X }
- X return(0);
- X
- X} /* windowup() */
- X
- X/* Scroll n lines down in window from line f to line t */
- GLOBL int windowdown(f, t, n)
- X register int f, t, n;
- X{
- X /* Set scrollregion from f to t and scroll down n lines */
- X if(_SR && windowset(f, t)) {
- X (void) cursorxy(0, f);
- X while(n-- > 0)
- X tputs(_SR, lines, _putch);
- X /* Reset scroll region to screen */
- X (void) windowset(0, lines - 1);
- X return(1);
- X }
- X /* Scroll down with a combination of insert and delete line */
- X else if(_AL && deleteline(t - n + 1 ,n)) {
- X (void) insertline(f, n);
- X return(1);
- X }
- X return(0);
- X
- X} /* windowdown() */
- X
- X/* Clear the screen */
- GLOBL VOID clearscreen()
- X{
- X tputs(_CL, lines, _putch);
- X curx = cury = 0;
- X
- X} /* clearscreen() */
- X
- X/* Clear from cursor position to end of line */
- GLOBL VOID clearline()
- X{
- X if( !_MS && vatt) /* Reset video attributes */
- X videoset(VA_NORMAL);
- X if(gatt) /* Reset graphic charset */
- X graphicset(GC_OFF);
- X tputs(_CE, 1, _putch);
- X
- X} /* clearline() */
- X
- X/* Clear to end of screen */
- GLOBL int cleartoend()
- X{
- X if( !_MS && vatt) /* Reset video attributes */
- X videoset(VA_NORMAL);
- X if(gatt) /* Reset graphic charset */
- X graphicset(GC_OFF);
- X if(_CD) {
- X tputs(_CD, lines, _putch);
- X return(1);
- X }
- X return(0);
- X
- X} /* cleartoend() */
- X
- X/* Clear screen from line f to line t */
- GLOBL VOID clearwindow(f, t)
- X register int f, t;
- X{
- X /* Clear one line only */
- X if(f == t) {
- X (void) cursorxy(0, f);
- X tputs(_CE, 1, _putch);
- X }
- X /* Try clear to end of screen */
- X else if(t == lines - 1 && _CD) {
- X (void) cursorxy(0, f);
- X tputs(_CD, lines, _putch);
- X }
- X /* Try clear by window scrolling */
- X else if( !windowup(f, t, t - f + 1)) {
- X /* Clear line by line */
- X while(f <= t) {
- X (void) cursorxy(0, f++);
- X tputs(_CE, 1, _putch);
- X }
- X (void) cursorxy(0, f);
- X }
- X
- X} /* clearwindow() */
- X
- X/* Turn on/off keypad transmit mode if f is set/unset */
- GLOBL VOID keypadxmit(f)
- X register int f;
- X{
- X if(f && _KS) /* Keypad transmit mode */
- X tputs(_KS, 1, _putch);
- X else if(_KE) /* Keypad normal mode */
- X tputs(_KE, 1, _putch);
- X
- X} /* keypadxmit() */
- X
- X/* Do some cursor functions defined in mask c */
- GLOBL VOID cursorset(c)
- X register int c;
- X{
- X if(c & CF_SAVE && _SC) { /* Save cursor */
- X if(vatt) /* Reset video attributes */
- X videoset(VA_NORMAL);
- X tputs(_SC, 1, _putch);
- X }
- X else if(c & CF_RESTORE && _RC) /* Restore cursor */
- X tputs(_RC, 1, _putch);
- X if(c & CF_VISIBLE && _VE) /* Cursor visible */
- X tputs(_VE, 1, _putch);
- X else if(c & CF_INVISIBLE && _VI) /* Cursor invisible */
- X tputs(_VI, 1, _putch);
- X
- X} /* cursorset() */
- X
- X/* Init graphical character set if f is set */
- GLOBL VOID initgraphics(f)
- X register int f;
- X{
- X register char *ac;
- X
- X GC_HB = '-'; /* Use ascii meta chars as default */
- X GC_VB = GC_LT = GC_RT = '|';
- X GC_TT = GC_BT = GC_UL = GC_LL = GC_UR = GC_LR = GC_TG = '+';
- X graphcap = 0;
- X if(f && (ac = _AC)) { /* If f is set and acsc is defined */
- X#ifdef AIX
- X GC_UL = *ac ? *ac++ : '+'; /* Upper left corner */
- X GC_HB = *ac ? *ac++ : '-'; /* Horizontal bar */
- X GC_UR = *ac ? *ac++ : '+'; /* Upper right corner */
- X GC_VB = *ac ? *ac++ : '|'; /* Vertical bar */
- X GC_LR = *ac ? *ac++ : '+'; /* Lower right corner */
- X GC_LL = *ac ? *ac++ : '+'; /* Lower left corner */
- X GC_TT = *ac ? *ac++ : '+'; /* Top tee */
- X GC_RT = *ac ? *ac++ : '|'; /* Right tee */
- X GC_BT = *ac ? *ac++ : '+'; /* Bottom tee */
- X GC_LT = *ac ? *ac++ : '|'; /* Left tee */
- X GC_TG = *ac ? *ac++ : '+'; /* Tag: plus sign */
- X#else /* !AIX */
- X# ifdef XENIX /* RG 11/22/91 */
- X if(*ac == '\0') {
- X GC_UL = _G2 ? *_G2 : '+'; /* Upper left corner */
- X GC_HB = _GH ? *_GH : '-'; /* Horizontal bar */
- X GC_UR = _G1 ? *_G1 : '+'; /* Upper right corner */
- X GC_VB = _GV ? *_GV : '|'; /* Vertical bar */
- X GC_LR = _G4 ? *_G4 : '+'; /* Lower right corner */
- X GC_LL = _G3 ? *_G3 : '+'; /* Lower left corner */
- X GC_TT = _GD ? *_GD : '+'; /* Top tee */
- X GC_RT = _GL ? *_GL : '|'; /* Right tee */
- X GC_BT = _GU ? *_GU : '+'; /* Bottom tee */
- X GC_LT = _GR ? *_GR : '|'; /* Left tee */
- X GC_TG = _GC ? *_GC : '+'; /* Tag: plus sign */
- X }
- X# endif /* XENIX */
- X do {
- X switch(*ac) {
- X default: /* Skip */
- X ++ac;
- X case '\0': /* End of acsc */
- X break;
- X case 'j': /* Lower right corner */
- X GC_LR = *++ac ? *ac : '+'; break;
- X case 'k': /* Upper right corner */
- X GC_UR = *++ac ? *ac : '+'; break;
- X case 'l': /* Upper left corner */
- X GC_UL = *++ac ? *ac : '+'; break;
- X case 'm': /* Lower left corner */
- X GC_LL = *++ac ? *ac : '+'; break;
- X case 'q': /* Horizontal bar */
- X GC_HB = *++ac ? *ac : '-'; break;
- X case 't': /* Left tee */
- X GC_LT = *++ac ? *ac : '|'; break;
- X case 'u': /* Right tee */
- X GC_RT = *++ac ? *ac : '|'; break;
- X case 'v': /* Bottom tee */
- X GC_BT = *++ac ? *ac : '+'; break;
- X case 'w': /* Top tee */
- X GC_TT = *++ac ? *ac : '+'; break;
- X case 'x': /* Vertical bar */
- X GC_VB = *++ac ? *ac : '|'; break;
- X case '`': /* Tag sign: diamond */
- X GC_TG = *++ac ? *ac : '+'; break;
- X case 'n': /* Alternate tag sign: plus */
- X if(*++ac && GC_TG == '+')
- X GC_TG = *ac;
- X break;
- X }
- X } while(*ac && *++ac);
- X#endif /* AIX */
- X graphcap = 1;
- X if(_EA)
- X tputs(_EA, 1, _putch);
- X }
- X
- X} /* initgraphics() */
- X
- X/*
- X * TERMINAL ROUTINES
- X */
- X
- X/* Switch terminal to raw mode */
- GLOBL VOID terminalraw(f)
- X register int f;
- X{
- X if(_TI && f)
- X tputs(_TI, 1, _putch);
- X curx = cury = HUGE;
- X keypadxmit(KP_XMIT);
- X flushout();
- X (void) ioctl(fileno(stdin), TCSETA, &raw);
- X
- X} /* terminalraw() */
- X
- X/* Reset terminal to initial mode */
- GLOBL VOID terminalreset(f)
- X register int f;
- X{
- X if(f && _TE)
- X tputs(_TE, 1, _putch);
- X curx = cury = HUGE;
- X keypadxmit(KP_NORMAL);
- X videoset(VA_NORMAL);
- X flushout();
- X (void) ioctl(fileno(stdin), TCSETA, &tty);
- X
- X} /* terminalreset() */
- X
- X/* Enable signal handling */
- GLOBL VOID enablesignals()
- X{
- X#ifdef BSD
- X raw.sg_flags &= ~RAW;
- X raw.sg_flags |= CBREAK;
- X#else /* SYSV */
- X raw.c_lflag |= ISIG;
- X#endif /* BSD */
- X flushout();
- X (void) ioctl(fileno(stdin), TCSETA, &raw);
- X
- X} /* enablesignals() */
- X
- X/* Disable signal handling */
- GLOBL VOID disablesignals()
- X{
- X#ifdef BSD
- X raw.sg_flags &= ~CBREAK;
- X raw.sg_flags |= RAW;
- X#else /* SYSV */
- X raw.c_lflag &= ~ISIG;
- X#endif /* BSD */
- X flushout();
- X (void) ioctl(fileno(stdin), TCSETA, &raw);
- X
- X} /* disablesignals() */
- X
- X/*
- X * INITIALIZATION AND RESET
- X */
- X
- X/* Init screen, return error message on error */
- GLOBL char *initscreen(term)
- X register char *term;
- X{
- X char termcap[TCAPLEN];
- X char *cp = termbuf, *pc;
- X
- X /* Get terminal type and init terminal data base */
- X if(term == NULL)
- X return("Terminal variable TERM not defined");
- X switch(tgetent(termcap, term)) {
- X case -1 :
- X return("Terminfo library not found");
- X case 0 :
- X return("Unknown terminal type");
- X }
- X
- X /* Get all needed terminal capabilities from data base */
- X if((columns = tgetnum("co")) <= 0)
- X columns = MINCOLS;
- X if((lines = tgetnum("li")) <= 0)
- X lines = MINLINS;
- X UP = tgetstr("up", &cp);
- X BC = tgetstr("bc", &cp);
- X if(pc = tgetstr("pc", &cp))
- X PC = *pc;
- X _CM = tgetstr("cm", &cp);
- X _CL = tgetstr("cl", &cp);
- X _CE = tgetstr("ce", &cp);
- X
- X /* Cursor motion, clear screen and clear line must be defined! */
- X if(_CM == NULL || _CE == NULL || _CL == NULL)
- X return("Terminal too stupid");
- X
- X _XR = tgetflag("xr");
- X _MS = tgetflag("ms");
- X _SG = tgetnum("sg");
- X#ifdef BSD
- X _UG = tgetnum("ug");
- X#else /* SYSV */
- X _UG = _SG;
- X#endif /* BSD */
- X _CD = tgetstr("cd", &cp);
- X _TI = tgetstr("ti", &cp);
- X _TE = tgetstr("te", &cp);
- X _KS = tgetstr("ks", &cp);
- X _KE = tgetstr("ke", &cp);
- X if((_ME = tgetstr("me", &cp)) == NULL)
- X _ME = tgetstr("se", &cp);
- X if((_MR = tgetstr("mr", &cp)) == NULL)
- X _MR = tgetstr("so", &cp);
- X if(_US = tgetstr("us", &cp)) {
- X if((_UE = tgetstr("ue", &cp)) && _ME && EQU(_ME, _UE))
- X _UE = NULL;
- X }
- X /* No more video attributes and no cursor visibility functions for */
- X /* terminals with standout mode and/or underline glitch (i.e. bando) */
- X if(_UG <= 0 && _SG <= 0) {
- X _MB = tgetstr("mb", &cp);
- X _MD = tgetstr("md", &cp);
- X _MH = tgetstr("mh", &cp);
- X _VS = tgetstr("vs", &cp);
- X _VI = tgetstr("vi", &cp);
- X _VE = tgetstr("ve", &cp);
- X }
- X _IC = tgetstr("ic", &cp);
- X _DC = tgetstr("dc", &cp);
- X _AL = tgetstr("al", &cp);
- X _DL = tgetstr("dl", &cp);
- X _CS = tgetstr("cs", &cp);
- X _NL = tgetstr("nl", &cp);
- X _CR = tgetstr("cr", &cp);
- X _LE = tgetstr("le", &cp);
- X _DO = tgetstr("do", &cp);
- X _SF = tgetstr("sf", &cp);
- X _SR = tgetstr("sr", &cp);
- X _SC = tgetstr("sc", &cp);
- X _RC = tgetstr("rc", &cp);
- X _BL = tgetstr("bl", &cp);
- X
- X#ifdef AIX
- X _AC = tgetstr("bx", &cp); /* Use box1 (bx) instead of acsc (ac) */
- X if( !(_AS = tgetstr("as", &cp)))
- X _AS = tgetstr("f1", &cp); /* 3.2: Use font1 (f1) instead of smacs (as) */
- X if( !(_AE = tgetstr("ae", &cp)))
- X _AE = tgetstr("f0", &cp); /* 3.2: Use font0 (f0) instead of rmacs (ae) */
- X#else /* ACSC */
- X _EA = tgetstr("eA", &cp);
- X _AC = tgetstr("ac", &cp);
- X _AS = tgetstr("as", &cp);
- X _AE = tgetstr("ae", &cp);
- X# ifdef XENIX /* RG 11/22/91 */
- X if(_AC == NULL) {
- X _AC = ""; /* Use empty string _AC as flag */
- X _AS = tgetstr("GS", &cp);
- X _AE = tgetstr("GE", &cp);
- X _G2 = tgetstr("G2", &cp);
- X _GH = tgetstr("GH", &cp);
- X _G1 = tgetstr("G1", &cp);
- X _GV = tgetstr("GV", &cp);
- X _G4 = tgetstr("G4", &cp);
- X _G3 = tgetstr("G3", &cp);
- X _GD = tgetstr("GD", &cp);
- X _GL = tgetstr("GL", &cp);
- X _GU = tgetstr("GU", &cp);
- X _GR = tgetstr("GR", &cp);
- X _GC = tgetstr("GC", &cp);
- X }
- X# endif /* XENIX */
- X#endif /* AIX */
- X
- X if(_CS && !_SF) {
- X if(_DO)
- X _SF = _DO;
- X else if(_NL)
- X _SF = _NL;
- X else
- X _SF = "\n";
- X }
- X if(_VS && !_VE)
- X _VE = _VS;
- X
- X /* Set capability flags */
- X glitchcap = _UG > 0 || _SG > 0;
- X scrollcap = (_AL && _DL) || (_CS && _SF && _SR);
- X cursorcap = 0;
- X if(_VE && _VI)
- X cursorcap |= CF_VISIBLE|CF_INVISIBLE;
- X if(_SC && _RC)
- X cursorcap |= CF_SAVE|CF_RESTORE;
- X videocap = 0;
- X if(_MR)
- X videocap |= VA_REVERSE;
- X if(_MB)
- X videocap |= VA_BLINK;
- X if(_MD)
- X videocap |= VA_BOLD;
- X if(_MH)
- X videocap |= VA_HALF;
- X if(_US)
- X videocap |= VA_UNDERLINE;
- X
- X /* Initialize key bindings */
- X initbindings(term, &cp);
- X
- X /* Get terminal driver data and initialize raw mode */
- X if(ioctl(fileno(stdin), TCGETA, &tty) < 0)
- X return("Error in ioctl");
- X#ifdef STRUCTCOPY
- X (void) STRUCTCOPY(tty, raw, sizeof(tty));
- X#else /* STRUCTASSIGN */
- X raw = tty;
- X#endif /* STRUCTCOPY */
- X
- X#ifdef BSD
- X ospeed = tty.sg_ospeed;
- X raw.sg_flags |= ANYP|RAW;
- X raw.sg_flags &= ~(ECHO|XTABS);
- X#else /* SYSV */
- X raw.c_cc[VMIN] = 1;
- X raw.c_cc[VTIME] = 0;
- X raw.c_iflag |= IGNBRK;
- X raw.c_iflag &= ~(ICRNL|ISTRIP);
- X raw.c_oflag |= ONLCR|TAB0;
- X raw.c_cflag |= CS8;
- X raw.c_cflag &= ~PARENB;
- X raw.c_lflag &= ~(ECHO|ICANON|ISIG);
- X#endif /* BSD */
- X
- X#if !defined(BSD) && !defined(HASFIONREAD)
- X /* Get keyboard flag and set to no delay mode */
- X kbflag = fcntl(fileno(stdin), F_GETFL, 0) & O_NDELAY;
- X#endif /* !BSD && !HASFIONREAD */
- X
- X return(NULL);
- X
- X} /* initscreen() */
- X
- X/* Restore screen and exit */
- GLOBL VOID exitscreen(rval)
- X int rval;
- X{
- X cursorset(CF_VISIBLE);
- X (void) cursorxy(0, lines-1);
- X terminalreset(1);
- X flushout();
- X exit(rval);
- X
- X} /* exitscreen() */
- X
- END_OF_FILE
- if test 30770 -ne `wc -c <'src/term.c'`; then
- echo shar: \"'src/term.c'\" unpacked with wrong size!
- fi
- # end of 'src/term.c'
- fi
- echo shar: End of archive 6 \(of 8\).
- cp /dev/null ark6isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 8 archives.
- rm -f ark[1-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-