home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-06 | 65.5 KB | 2,412 lines |
- Newsgroups: comp.sources.unix
- From: klin@iat.uni-paderborn.de (Peter Klingebiel)
- Subject: v26i071: utree - screen oriented filesystem utility (V3.03b-um), Part08/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 71
- Archive-Name: utree/part08
-
- #! /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 8 (of 8)."
- # Contents: src/tree.c
- # Wrapped by vixie@cognition.pa.dec.com on Mon Sep 7 14:39:58 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'src/tree.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/tree.c'\"
- else
- echo shar: Extracting \"'src/tree.c'\" \(63122 characters\)
- sed "s/^X//" >'src/tree.c' <<'END_OF_FILE'
- X/*
- X * TREE.C
- X * UTREE tree menu routines.
- X * 3.01-um klin, Tue Jun 4 14:19:16 1991
- X * klin, Tue Oct 15 14:02:37 1991, Handling of symlinks changed
- X * klin, Sat Oct 26 15:07:06 1991, Tagging files changed
- X * Sorting and zooming changed
- X * Select directories added
- X * Print tree list added
- X * More local functions
- X * 3.02-um klin, Fri Nov 1 10:46:14 1991, Screen layout changed
- X * Goto parent added
- 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 22:58:03 1992, Screen layout changed
- X * Shell escape, variables and
- X * filetype commands changed
- X * klin, Sat Feb 15 14:44:52 1992, Video handling and partinioning of
- X * directory and file windows changed
- X * klin, Sat Feb 22 10:34:03 1992, Many commands changed to work
- X * on current directory or subtree
- X * or tagged files
- X * klin, Sun Feb 23 17:32:57 1992, Key handling and key bindings
- X * changed
- X * No removing of subtrees
- X * a klin, Sun Mar 15 19:08:25 1992, Bug fix in gotree()
- 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 tree.c";
- X#endif /* !lint */
- X
- X#include "defs.h"
- X
- X/* ---- Local variables and definitions ------------------------------- */
- X
- LOCAL dlist *tdlist = DNULL; /* Top dlist on tree screen */
- LOCAL dlist *mdlist = DNULL; /* Marked dlist entry */
- LOCAL dlist *tdlast = DNULL; /* Last tdlist */
- LOCAL dlist *cdlast = DNULL; /* Last current dlist entry */
- LOCAL char *mustup = "Tree must be updated. Continue ?";
- LOCAL char *cancel = "(Hit BREAK to abort)";
- X
- X/* Tree menu commands in help line */
- LOCAL char *tmline =
- X" Help Backup Chdir Find Grep Info List Mkdir Out Rmdir Stat Tag Untag Quit";
- LOCAL char *menuline = NULL;
- X
- X#define BCOL 0 /* Column for tree position bar */
- X#define SCOL 1 /* Column for tag or mark sign */
- X#define TCOL 2 /* Startcolumn for directory tree */
- X#define UCOL -1 /* Column for number of files unknown */
- X#define FCOL -5 /* Column for number of files */
- X#define SLIN (lastdline+1) /* Line for separator line */
- X#define NFFMT "%5d" /* Format for number of files */
- X
- X#define ONTR(c) ((c) < 'a') /* Command works on subtree */
- X#define ONTG(c) ((c) < 'a') /* Command works on tagged files */
- X
- X/* ---- External variables and functions ------------------------------ */
- X
- XEXTRN FILE *popen();
- XEXTRN char *writedlist();
- XEXTRN char *selectdir();
- LOCAL char *dirselect();
- X
- X/* ---- Functions and procedures -------------------------------------- */
- X
- X/*
- X * TREE DISPLAY ROUTINES
- X */
- X
- X/* Display files of current directory in file window starting at line l */
- LOCAL VOID showflist(l)
- X register int l;
- X{
- X register int f, i;
- X
- X if((f = (l - firstfline) * fperline) < CNFIL) {
- X while(f < CNFIL && l++ <= lastfline)
- X for(i = 0; f < CNFIL && i < fperline; f++, i++) {
- X putfile(cdlist, f, 0);
- X clearline();
- X }
- X if(l <= lastfline)
- X clearwindow(l, lastfline);
- X }
- X else if(CNFIL == 0 && l == firstfline)
- X clearwindow(l, lastfline);
- X
- X} /* showflist() */
- X
- X/* Display directory list entry dp */
- LOCAL VOID showdlist(dp, f)
- X register dlist *dp;
- X register int f;
- X{
- X /* Is directory on screen? */
- X if(dp && DTROW(dp) >= firstdline && DTROW(dp) <= lastdline) {
- X /* Display directory tag marker */
- X if(DNTAG(dp)) {
- X (void) setgraphic(GC_ON);
- X (void) putcxy(SCOL, DTROW(dp), GC_TG);
- X (void) setgraphic(GC_OFF);
- X }
- X else
- X (void) putcxy(SCOL, DTROW(dp), ' ');
- X /* Display directory filename */
- X if(f && dp == cdlist) { /* Highlight current directory */
- X if(CCANC) {
- X setvideo(DA_BOLDREV);
- X (void) putfxy(TCOL+DTCOL(dp)-1, DTROW(dp), 0, ">%s ", CFNAM);
- X }
- X else {
- X setvideo(DA_HALFREV);
- X (void) putfxy(TCOL+DTCOL(dp)-1, DTROW(dp), 0, " %s ", CFNAM);
- X }
- X }
- X else { /* Other directory */
- X setvideo(DCANC(dp) ? DA_BOLD : DA_HALF);
- X (void) putfxy(TCOL+DTCOL(dp)-1, DTROW(dp), 0, " %s ", DFNAM(dp));
- X }
- X /* Display number of files if known */
- X setvideo(DA_NORMAL);
- X if(DCANC(dp)) {
- X if(DFLAG(dp) != FL_FIL)
- X putcxy(UCOL, DTROW(dp), '?');
- X else
- X (void) putfxy(FCOL, DTROW(dp), 0, NFFMT, DNFIL(dp));
- X }
- X else
- X putcxy(UCOL, DTROW(dp), '-');
- X }
- X
- X} /* showdlist() */
- X
- X/* Display whole directory line for directory dp */
- LOCAL VOID showdline(dp)
- X register dlist *dp;
- X{
- X register int i, j;
- X
- X /* Is directory on screen? */
- X if(dp && DTROW(dp) >= firstdline && DTROW(dp) <= lastdline) {
- X (void) cursorxy(TCOL, DTROW(dp));
- X clearline();
- X (void) setgraphic(GC_ON);
- X if(dp == droot) /* Root directory */
- X (void) putchar(DNEXT(dp) ? GC_UL : GC_HB);
- X else { /* Other directory */
- X (void) putchar(DNEXT(dp) ? GC_VB : GC_LL);
- X for(i = 1, j = DLEVL(dp) - 1; i < j; i++)
- X if(DINFO(dp) & (1 << (i-1)))
- X putcxy(TCOL+i*indent, DTROW(dp), GC_VB);
- X if(DINFO(dp) & (1 << (i-1)))
- X putcxy(TCOL+i*indent, DTROW(dp), GC_LT);
- X else
- X putcxy(TCOL+i*indent, DTROW(dp), GC_LL);
- X }
- X for(i = 2; i < indent; i++)
- X (void) putchar(GC_HB);
- X (void) setgraphic(GC_OFF);
- X showdlist(dp, 0); /* Display name */
- X }
- X
- X} /* showdline() */
- X
- X/* Display the directory list from line f to line t */
- LOCAL VOID showdtree(f, t, c)
- X register int f, t, c;
- X{
- X register dlist *dp;
- X
- X /* Search for first directory to print ... */
- X for(dp = tdlist; dp && DTROW(dp) < f; dp = (dlist *) DNEXT(dp))
- X ;
- X /* ... and print out from f to t */
- X for( ; dp && DTROW(dp) <= t; dp = (dlist *) DNEXT(dp))
- X showdline(dp);
- X /* Clear to end of tree window */
- X if(c && dp && DTROW(dp) < lastdline)
- X clearwindow(DTROW(dp), lastdline);
- X
- X} /* showdtree() */
- X
- X/* Display tree position bar */
- LOCAL VOID showtbar()
- X{
- X static int bar = 0;
- X register dlist *dp;
- X register int f, l, i;
- X
- X if(dircount > (ndlines + 1)) { /* More dirs than lines */
- X dp = tdlist;
- X while(DNEXT(dp) && DTROW(dp) < lastdline)
- X dp = (dlist *) DNEXT(dp);
- X f = ((DDNUM(tdlist) + 1) * ndlines) / dircount + firstdline;
- X l = ((DDNUM(dp) + 1) * ndlines) / dircount + firstdline;
- X if(f <= firstdline)
- X f = DPREV(tdlist) ? firstdline + 1 : firstdline;
- X if(l >= lastdline)
- X l = DNEXT(dp) ? lastdline - 1 : lastdline;
- X i = firstdline;
- X while(i < f)
- X putcxy(BCOL, i++, ' ');
- X if(videomode && (videocap & VA_REVERSE)) {
- X setvideo(DA_HALFREV);
- X putcxy(BCOL, i++, ' ');
- X while(i <= l)
- X putcxy(BCOL, i++, ' ');
- X setvideo(DA_NORMAL);
- X }
- X else {
- X (void) setgraphic(GC_ON);
- X putcxy(BCOL, i++, GC_TT);
- X while(i < l)
- X putcxy(BCOL, i++, GC_VB);
- X putcxy(BCOL, i++, GC_BT);
- X (void) setgraphic(GC_OFF);
- X }
- X while(i <= lastdline)
- X putcxy(BCOL, i++, ' ');
- X bar = 1;
- X }
- X else if(bar) {
- X for(i = firstdline; i <= lastdline; i++)
- X putcxy(BCOL, i, ' ');
- X bar = 0;
- X }
- X
- X} /* showtbar() */
- X
- X/* Display separator line between tree and file window */
- LOCAL VOID showsline()
- X{
- X static int lb = 0;
- X register dlist *dp;
- X register char *cp, *cz;
- X register int i, j;
- X
- X cp = CPNAM + strlen(rootdir);
- X cz = CZOOM ? CZOOM : "*";
- X setvideo(DA_REVERSE);
- X if(*cp)
- X i = putfxy(0, SLIN, 0, ".%s/%s: %d file(s) %d dir(s)", cp, cz, CNFIL, CNDIR);
- X else
- X i = putfxy(0, SLIN, 0, "./%s: %d file(s) %d dir(s)", cz, CNFIL, CNDIR);
- X while(i++ < columns)
- X (void) putchar(' ');
- X setvideo(DA_NORMAL);
- X
- X} /* showsline() */
- X
- X/*
- X * TREE SCREEN UPDATE AND REFRESH
- X */
- X
- X/* Update tree screen */
- LOCAL int updatetree(f)
- X register int f;
- X{
- X register int n, rv;
- X
- X if(treeflag & SF_LIST) { /* Check current directory */
- X if((CFLAG != FL_FIL || changedlist(cdlist)) && newflist(cdlist) != RV_OK)
- X return(RV_ERR);
- X }
- X rv = RV_OK;
- X if(keypressed()) /* There are chars in input buffer */
- X return(rv);
- X if(treeflag == SF_FULL) { /* Full screen update */
- X clearscreen();
- X cdlast = tdlast = DNULL;
- X }
- X if(treeflag & SF_TREE) { /* Tree screen */
- X n = tdlast ? DDNUM(tdlast) - DDNUM(tdlist) : 0;
- X if(CANSCROLL && n < 0 && n > -ndlines) {
- X (void) windowup(firstdline, lastdline, -n);
- X showdtree(lastdline + n + 1, lastdline, 0);
- X showdlist(cdlast, 0);
- X }
- X else if(CANSCROLL && n > 0 && n < ndlines) {
- X (void) windowdown(firstdline, lastdline, n);
- X showdtree(firstdline, firstdline + n - 1, 0);
- X showdlist(cdlast, 0);
- X }
- X else
- X showdtree(firstdline, lastdline, treeflag != SF_FULL);
- X treeflag |= SF_PBAR;
- X }
- X else if(treeflag & SF_LAST) /* Last directory */
- X showdlist(cdlast, 0);
- X if(treeflag & SF_PBAR) /* Tree position bar */
- X showtbar();
- X if(treeflag & SF_LIST) { /* Current directory */
- X showdlist(cdlist, 1);
- X showsline();
- X }
- X else if(treeflag & SF_SEPL)
- X showsline();
- X if(treeflag & SF_FILE) /* File list */
- X showflist(firstfline);
- X if(treeflag & SF_HELP && !f) /* Help line */
- X putmenu("TREE:", menuline);
- X if(treeflag & SF_ECHO && !f) /* Echo line */
- X (void) putecho("%s: %d dir(s) %d file(s)", rootdir, dircount, filecount);
- X /* Position to current directory, set variables and return */
- X (void) cursorxy(TCOL+DTCOL(cdlist)-1, DTROW(cdlist));
- X cdlast = cdlist;
- X tdlast = tdlist;
- X treeflag = 0;
- X return(rv);
- X
- X} /* updatetree() */
- X
- X/*
- X * SCROLL UP OR DOWN DIRECTORY TREE
- X */
- X
- X/* Scroll directory tree */
- LOCAL int scrolltree(dir)
- X register int dir;
- X{
- X register dlist *dp;
- X register int i;
- X
- X /* Is scrolling possible? */
- X if((dir < 0 && DPREV(tdlist) == GNULL) || (dir > 0 && CNEXT == GNULL))
- X return(0);
- X if(dir < 0) { /* Scroll down */
- X tdlist = (dlist *) DPREV(tdlist);
- X if(CANSCROLL) {
- X (void) windowdown(firstdline, lastdline, 1);
- X showdline(tdlist);
- X treeflag |= SF_MOVE|SF_PBAR;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST|SF_PBAR;
- X }
- X else { /* Scroll up */
- X for(dp = tdlist, i = ndlines; i >= 0 ; i--)
- X if(((dp = (dlist *) DNEXT(dp))) == DNULL)
- X return(0);
- X tdlist = (dlist *) DNEXT(tdlist);
- X if(CANSCROLL) {
- X (void) windowup(firstdline, lastdline, 1);
- X for(dp = tdlist; DTROW(dp) < lastdline; dp = (dlist *) DNEXT(dp))
- X ;
- X showdline(dp);
- X treeflag |= SF_MOVE|SF_PBAR;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST|SF_PBAR;
- X }
- X if(DTROW(cdlist) < firstdline) /* Change current directory */
- X (void) gotree(1); /* if out of screen */
- X else if(DTROW(cdlist) > lastdline)
- X (void) gotree(-1);
- X return(1);
- X
- X} /* scrolltree() */
- X
- X/*
- X * CHECK TREE
- X */
- X
- X/* Check if all directories in tree are unchanged or read in */
- LOCAL int checktree(msg)
- X register char *msg;
- X{
- X register dlist *dp;
- X register int c;
- X
- X if(VARSET(V_ST) && scandlist(cdlist) != RV_OK)
- X return(RV_NUL);
- X for(dp = (dlist *) CNEXT; dp && DLEVL(dp) > CLEVL; dp = (dlist *) DNEXT(dp)) {
- X if(DFLAG(dp) != FL_FIL) {
- X ++buildflag;
- X bell(VARSET(V_BL));
- X puthelp("%s (Y:continue ELSE:quit)", who);
- X c = hitakey(msg, echoline, DA_NONE);
- X return(c == 'y' ? RV_OK : c);
- X }
- X }
- X return(RV_OK);
- X
- X} /* checktree() */
- X
- X/*
- X * TAG/UNTAG FILES IN TREE
- X */
- X
- X/* Tag files in directory tree */
- LOCAL int tagtree(t)
- X register int t;
- X{
- X char input[PATLEN];
- X register dlist *dp;
- X register int f, c, ff, nt;
- X
- X who = t ? "TAG TREE" : "TAG DIRECTORY";
- X if(t && (c = checktree(mustup)) != RV_OK)
- X return(c);
- X
- X puthelp("%s: Give file pattern (CR:%s)", who, tpattern[0] ? tpattern : "quit");
- X if((c = getpattern(input, "Tag which files:")) == RV_OK)
- X (void) strcpy(tpattern, input);
- X else if(c < RV_NUL || (c == RV_NUL && tpattern[0] == '\0'))
- X return(c);
- X
- X /* Walk thru subtree */
- X puthelp("%s %s", who, cancel);
- X dp = cdlist;
- X ff = 0;
- X do {
- X nt = DNTAG(dp);
- X if( !DCANC(dp))
- X continue;
- X else if(DFLAG(dp) != FL_FIL && (f = newflist(dp)) != RV_OK) /* Update! */
- X return(f);
- X else if(keypressed() && hitakey(NULL) < RV_NUL)
- X break;
- X /* Walk thru file list */
- X for(f = 0; f < DNFIL(dp); f++)
- X if(umatch(dp, f, tpattern) > 0) {
- X FITAG(dp, f) = FF_TAG;
- X ++DNTAG(dp);
- X ++ff;
- X }
- X if(nt != DNTAG(dp))
- X showdlist(dp, 0);
- X } while(t && (dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X
- X if(ff > 0)
- X treeflag |= SF_FILE|SF_LIST;
- X puthelp("%s: %s %s", who, tpattern, hitkey);
- X (void) putecho("Tagged %d file(s) matching %s", ff, tpattern);
- X return(hitakey(NULL));
- X
- X} /* tagtree() */
- X
- X/* Untag files in directory tree */
- LOCAL int untagtree(t)
- X register int t;
- X{
- X char pat[PATLEN];
- X register dlist *dp;
- X register int f, c, ff, nt;
- X
- X who = t ? "UNTAG TREE" : "UNTAG DIRECTORY";
- X if(t && (c = checktree(mustup)) != RV_OK)
- X return(c);
- X
- X puthelp("%s: Give file pattern (CR:all files)", who);
- X if((c = getpattern(pat, "Untag which files:")) < RV_NUL)
- X return(c);
- X else if(c == RV_NUL)
- X (void) strcpy(pat, "*");
- X
- X /* Walk thru subtree */
- X puthelp("%s %s", who, cancel);
- X dp = cdlist;
- X ff = 0;
- X do {
- X nt = DNTAG(dp);
- X if( !DCANC(dp))
- X continue;
- X else if(DFLAG(dp) != FL_FIL && (f = newflist(dp)) != RV_OK)
- X return(f);
- X else if(keypressed() && hitakey(NULL) < RV_NUL)
- X break;
- X /* Walk thru file list */
- X for(f = 0; f < DNFIL(dp); f++)
- X if(ISTAG(dp, f) && umatch(dp, f, pat) > 0) {
- X FITAG(dp, f) = FF_NONE;
- X if(DNTAG(dp) > 0)
- X --DNTAG(dp);
- X ++ff;
- X }
- X if(nt != DNTAG(dp))
- X showdlist(dp, 0);
- X } while(t && (dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X
- X if(ff > 0)
- X treeflag |= SF_FILE|SF_LIST;
- X puthelp("%s: %s %s", who, pat, hitkey);
- X (void) putecho("Untagged %d file(s) matching %s", ff, pat);
- X return(hitakey(NULL));
- X
- X} /* untagtree() */
- X
- X/* Check if there are tagged files */
- LOCAL int checktagged()
- X{
- X register dlist *dp;
- X register int f, n;
- X
- X /* Walk thru subtree */
- X dp = cdlist;
- X n = 0;
- X do {
- X if( !DCANC(dp))
- X continue;
- X /* Walk thru file list */
- X for(f = 0; f < DNFIL(dp); f++)
- X if(ISTAG(dp, f))
- X ++n;
- X } while((dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X return(n);
- X
- X} /* checktagged() */
- X
- X/*
- X * COMMANDS WORKING ON TAGGED FILES
- X */
- X
- X/* Remove tagged files in tree */
- GLOBL int removetagged()
- X{
- X register dlist *dp;
- X register int c, f, n, rflag;
- X
- X who = "REMOVE TAGGED FILES";
- X if(checktagged() == 0) { /* No tagged files */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No tagged files found"));
- X }
- X
- X puthelp("%s (Y:request N:don't request ELSE:quit)", who);
- X c = hitakey("Request before removing tagged files ?", echoline, DA_NONE);
- X if( !(c == 'y' || c == 'n'))
- X return(c);
- X rflag = c == 'y';
- X
- X if(rflag)
- X puthelp("REMOVE FILE (Y:remove Q:quit ELSE:don't remove)");
- X else
- X puthelp("%s (In progress ...)", who);
- X
- X /* Walk thru subtree */
- X dp = cdlist;
- X n = 0;
- X do {
- X if(CNTAG > 0) { /* Contains tagged files */
- X treeflag &= ~(SF_ECHO|SF_HELP);
- X (void) updatetree(0);
- X /* Walk thru file list */
- X for(f = CNFIL - 1; f >= 0; f--) {
- X if(ISTAG(cdlist, f)) {
- X c = removefile(cdlist, f, rflag);
- X if(c == 'q' || c < RV_NUL)
- X goto ENDLOOP;
- X else if(c == RV_OK) {
- X ++n;
- X FITAG(cdlist, f) = FF_NONE;
- X if(CNTAG > 0)
- X --CNTAG;
- X if(rflag)
- X showflist(firstfline);
- X }
- X }
- X }
- X if(CFLAG == FL_CHG) {
- X if((c = newflist(cdlist)) != RV_OK)
- X goto ENDLOOP;
- X else
- X showdlist(cdlist, 0);
- X }
- X }
- X } while(gotree(1) && CLEVL > DLEVL(dp));
- X
- XENDLOOP:
- X if(c == RV_END)
- X return(c);
- X while(cdlist != dp) /* Position to starting directory */
- X (void) gotree(-1);
- X puthelp("%s %s", who, hitkey);
- X if(n > 0) {
- X treeflag = SF_FULL;
- X (void) putecho("Removed %d tagged file(s)", n);
- X }
- X else
- X (void) putecho("No files removed");
- X return(hitakey(NULL));
- X
- X} /* removetagged() */
- X
- LOCAL char *dirselect(what)
- X register char *what;
- X{
- X register char *dn;
- X
- X dn = selectdir(what);
- X treeflag = SF_FULL;
- X treeflag &= ~(SF_HELP|SF_ECHO);
- X (void) updatetree(0);
- X return(dn);
- X
- X} /* dirselect() */
- X
- X/* Move tagged files in tree */
- GLOBL int movetagged()
- X{
- X char name[NAMELEN];
- X struct stat st;
- X register dlist *dp;
- X register char *to;
- X register int c, f, n, rflag;
- X
- X who = "MOVE TAGGED FILES";
- X if(checktagged() == 0) { /* No tagged files */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No tagged files found"));
- X }
- X
- 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 = dirselect("moving files")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X
- X puthelp("%s (Y:request N:don't request ELSE:quit)", who);
- X c = hitakey("Request before moving tagged files ?", echoline, DA_NONE);
- X if( !(c == 'y' || c == 'n'))
- X return(c);
- X rflag = c == 'y';
- X
- X if(rflag)
- X puthelp("MOVE FILE (Y:copy Q:quit ELSE:don't copy)");
- X else
- X puthelp("%s (In progress ...)", who);
- X
- X /* Walk thru subtree */
- X dp = cdlist;
- X n = 0;
- X do {
- X if(CNTAG > 0) { /* Contains tagged files */
- X treeflag &= ~(SF_ECHO|SF_HELP);
- X (void) updatetree(0);
- X /* Walk thru file list */
- X for(f = CNFIL - 1; f >= 0; f--) {
- X if(ISTAG(cdlist, f)) {
- X c = movefile(cdlist, f, to, rflag);
- X if(c == 'q' || c < RV_NUL)
- X goto ENDLOOP;
- X else if(c == RV_OK) {
- X ++n;
- X FITAG(cdlist, f) = FF_NONE;
- X if(CNTAG > 0)
- X --CNTAG;
- X }
- X }
- X }
- X if(CFLAG == FL_CHG) {
- X if((c = newflist(cdlist)) != RV_OK)
- X goto ENDLOOP;
- X else
- X showdlist(cdlist, 0);
- X }
- X }
- X } while(gotree(1) && CLEVL > DLEVL(dp));
- X
- XENDLOOP:
- X if(c == RV_END)
- X return(c);
- X checkdlist(to);
- X while(cdlist != dp) /* Position to starting directory */
- X (void) gotree(-1);
- X puthelp("%s %s", who, hitkey);
- X if(n > 0) {
- X treeflag = SF_FULL;
- X (void) putecho("Moved %d file(s) to %s", n, to);
- X }
- X else
- X (void) putecho("No files moved");
- X return(hitakey(NULL));
- X
- X} /* movetagged() */
- X
- X/* Copy tagged files in tree */
- GLOBL int copytagged()
- X{
- X char name[NAMELEN];
- X struct stat st;
- X register dlist *dp;
- X register char *to;
- X register int c, f, n, rflag;
- X
- X who = "COPY TAGGED FILES";
- X if(checktagged() == 0) { /* No tagged files */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No tagged files found"));
- X }
- X
- 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 = dirselect("copying files")) == NULL) {
- X fileflag |= SF_ECHO|SF_HELP;
- X return(RV_NUL);
- X }
- X
- X puthelp("%s (Y:request N:don't request ELSE:quit)", who);
- X c = hitakey("Request before copying tagged files ?", echoline, DA_NONE);
- X if( !(c == 'y' || c == 'n'))
- X return(c);
- X rflag = c == 'y';
- X
- X if(rflag)
- X puthelp("COPY FILE (Y:copy Q:quit ELSE:don't copy)");
- X else
- X puthelp("%s (In progress ...)", who);
- X
- X /* Walk thru subtree */
- X dp = cdlist;
- X n = 0;
- X do {
- X if(CNTAG > 0) { /* Contains tagged files */
- X treeflag &= ~(SF_ECHO|SF_HELP);
- X (void) updatetree(0);
- X /* Walk thru file list */
- X for(f = CNFIL - 1; f >= 0; f--) {
- X if(ISTAG(cdlist, f)) {
- X c = copyfile(cdlist, f, to, rflag);
- X if(c == 'q' || c < RV_NUL)
- X goto ENDLOOP;
- X else if(c == RV_OK) {
- X ++n;
- X FITAG(cdlist, f) = FF_NONE;
- X if(CNTAG > 0)
- X --CNTAG;
- X }
- X }
- X }
- X }
- X } while(gotree(1) && CLEVL > DLEVL(dp));
- X
- XENDLOOP:
- X if(c == RV_END)
- X return(c);
- X checkdlist(to);
- X while(cdlist != dp) /* Position to starting directory */
- X (void) gotree(-1);
- X puthelp("%s %s", who, hitkey);
- X if(n > 0) {
- X treeflag = SF_FULL;
- X (void) putecho("Copied %d file(s) to %s", n, to);
- X }
- X else
- X (void) putecho("No files copied");
- X return(hitakey(NULL));
- X
- X} /* copytagged() */
- X
- X/*
- X * RESIZE DIRECTORY TREE WINDOW
- X */
- X
- X/* Recalculate and update dlists on directory window */
- GLOBL VOID calculatetree(n)
- X register int n;
- X{
- X register dlist *dp;
- X
- X if(tdlist && cdlist) { /* Tree window needs update */
- X if(n < 0 && DTROW(cdlist) > lastdline) {
- X while(DTROW(cdlist) > lastdline)
- X tdlist = (dlist *) DNEXT(tdlist);
- X }
- X else if(n > 0) {
- X for( ; n > 0; n--) {
- X for(dp = cdlist; dp && DTROW(dp) < lastdline; dp = (dlist *) DNEXT(dp))
- X ;
- X if(DPREV(tdlist) && dp == DNULL)
- X tdlist = (dlist *) DPREV(tdlist);
- X else
- X break;
- X }
- X }
- X }
- X
- X} /* calculatetree() */
- X
- X/* Enlarge or shrink the tree window */
- LOCAL int resizetree(dir)
- X register int dir;
- X{
- X register dlist *dp;
- X
- X /* Enlarge tree window if possible */
- X if(dir > 0 && nflines > MINFIL) {
- X ++lastdline;
- X for(dp = cdlist; dp && DTROW(dp) < lastdline; dp = (dlist *) DNEXT(dp))
- X ;
- X if(DPREV(tdlist) && dp == DNULL) {
- X tdlist = (dlist *) DPREV(tdlist);
- X if(CANSCROLL) {
- X (void) windowdown(firstdline, lastfline, 1);
- X showdline(tdlist);
- X treeflag |= SF_MOVE;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST;
- X }
- X else if(CANSCROLL) {
- X (void) windowdown(lastdline, lastfline, 1);
- X showdline(dp);
- X treeflag |= SF_MOVE;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST|SF_FILE;
- X ++ndlines;
- X --nflines;
- X ++firstfline;
- X checklines(0);
- X }
- X /* Shrink tree window if possible */
- X else if(dir < 0 && nflines < calculatelines()) {
- X --ndlines;
- X --firstfline;
- X if(DTROW(cdlist) == lastdline) {
- X tdlist = (dlist *) DNEXT(tdlist);
- X if(CANSCROLL) {
- X (void) windowup(firstdline, lastfline, 1);
- X showflist(lastfline);
- X treeflag |= SF_MOVE;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST|SF_FILE;
- X }
- X else if(CANSCROLL) {
- X (void) windowup(lastdline, lastfline, 1);
- X showflist(lastfline);
- X treeflag |= SF_MOVE;
- X }
- X else
- X treeflag |= SF_TREE|SF_LIST|SF_FILE;
- X --lastdline;
- X ++nflines;
- X checklines(0);
- X }
- X else
- X return(0);
- X
- X treeflag |= SF_SEPL|SF_PBAR;
- X return(1);
- X
- X} /* resizetree() */
- X
- X/*
- X * INFORMATION AND STATUS OF DIRECTORY
- X */
- X
- X/* Show some directory information */
- LOCAL int infodir()
- X{
- X char buf[EXECLEN];
- X struct stat st;
- X register FILE *pp;
- X register int i;
- X
- X who = "INFO";
- X puthelp("%s: %s %s", who, CPNAM, hitkey);
- X if((*statfun)(CPNAM, &st))
- X return(errequest(CFNAM, "Cannot stat"));
- X
- X (void) putecho("Scanning disk for disk usage, wait a moment ... ");
- X flushout();
- X (void) sprintf(buf, "%s %s", DUDIR, CPNAM);
- X if(pp = popen(buf, "r")) { /* Let du summarize used blocks */
- X (void) fgets(buf, sizeof(buf), pp);
- X (void) pclose(pp);
- X i = 0;
- X while(buf[i] >= '0' && buf[i] <= '9')
- X ++i;
- X buf[i] = '\0';
- X }
- X else /* Error in calling du */
- X (void) strcpy(buf, "?");
- X (void) putecho("Access:%s Blocks:%s Files:%d Dirs:%d Date:%s",
- X fileaccess(&st), buf, CNFIL, CNDIR, ctime(&st.st_mtime));
- X return(hitakey(NULL));
- X
- X} /* infodir() */
- X
- X/* Show and change directory status */
- LOCAL int statusdir()
- X{
- X register int c;
- X
- X c = statusfile(CPNAM, 0);
- X if(buildflag) { /* Rebuilding needed */
- X c = newflist(cdlist);
- X buildflag = 0;
- X }
- X return(c);
- X
- X} /* statusdir() */
- X
- X/*
- X * BACKUP DIRECTORY OR TREE
- X */
- X
- X/* Create filelist for backup */
- LOCAL int backuplist(name, t)
- X register char *name;
- X register int t;
- X{
- X char fname[NAMELEN];
- X register FILE *file;
- X register dlist *dp;
- X register char *dname;
- X register int dlen, i;
- X
- X (void) strcpy(fname, pathname(name, CPNAM));
- X if(file = fopen(fname, "w")) {
- X /* Write out tree or subtree list */
- X dlen = strlen(CPNAM);
- X for(i = 0; i < CNFIL ; i++)
- X if( !t || ISTAG(cdlist, i)) {
- X (void) fprintf(file, "%s\n", FFNAM(cdlist, i));
- X FITAG(cdlist, i) = FF_NONE;
- X if(CNTAG > 0)
- X --CNTAG;
- X }
- X for(dp = (dlist *) CNEXT; dp && DLEVL(dp) > CLEVL; dp = (dlist *) DNEXT(dp)) {
- X if( !DCANC(dp))
- X continue;
- X dname = &(DPNAM(dp)[dlen+1]);
- X for(i = 0; i < DNFIL(dp); i++)
- X if( !t || ISTAG(dp, i)) {
- X (void) fprintf(file, "%s\n", pathname(FFNAM(dp, i), dname));
- X FITAG(dp, i) = FF_NONE;
- X if(DNTAG(dp) > 0)
- X --DNTAG(dp);
- X }
- X }
- X (void) fclose(file);
- X }
- X else {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(prgname, "Cannot create backup list file"));
- X }
- X
- X checkdlist(fname); /* Update needed? */
- X return(buildflag ? updatedlist() : RV_OK);
- X
- X} /* backuplist() */
- X
- X/* Backup directory/subtree or tagged files in subtree */
- LOCAL int backupdir(t)
- X register int t;
- X{
- X char name[INPLEN], list[NAMELEN], buf[EXECLEN];
- X register dlist *dp;
- X register int c;
- X
- X who = t ? "BACKUP TAGGED FILES" : "BACKUP TREE";
- X if( !VARSET(V_BK)) { /* No backup program */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(prgname, "No backup program defined"));
- X }
- X else if(t && checktagged() == 0) { /* No tagged files */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No tagged files found"));
- X }
- X else if((c = changelist(cdlist, who)) != RV_OK)
- X return(c);
- X
- X /* Update subtree if needed */
- X if( !t) {
- X if((c = checktree(mustup)) != RV_OK)
- X return(c);
- X for(dp = (dlist *) CNEXT; dp && DLEVL(dp) > CLEVL; dp = (dlist *) DNEXT(dp))
- X if(DFLAG(dp) != FL_FIL) {
- X if((c = newflist(dp)) != RV_OK)
- X return(c);
- X else
- X treeflag |= SF_TREE|SF_LIST;
- X }
- X if(treeflag)
- X (void) updatetree(0);
- X }
- X
- X puthelp("%s: Give filename for backup list (CR:$HOME/%s)", who, UTBACK);
- X c = putecho("List file name:");
- X if((c = getline(name, sizeof(name), c, 0, NULL, CLIST, 1)) == RV_OK)
- X (void) strcpy(list, name);
- X else if(c == RV_NUL)
- X (void) strcpy(list, pathname(UTBACK, home));
- X else
- X return(c);
- X if((c = backuplist(list, t)) != RV_OK)
- X return(c);
- X
- X /* Build command line and call backup program */
- X treeflag = SF_FULL;
- X if( !VARSET(V_BKO))
- X (void) sprintf(buf, "%s %s", VARVAL(V_BK), list);
- X else
- X (void) sprintf(buf, "%s %s %s", VARVAL(V_BK), VARVAL(V_BKO), list);
- X puthelp("%s %s", who, cancel);
- X (void) putecho("Executing backup program %s ...", VARVAL(V_BK));
- X c = callsystem(buf, 1, 0);
- X
- X puthelp("%s %s", who, hitkey);
- X if(c != RV_OK)
- X return(errequest(VARVAL(V_BK), "Error in backup"));
- X bell(VARSET(V_BL));
- X return(hitakey("Backup done", echoline, DA_NONE));
- X
- X} /* backupdir() */
- X
- X/*
- X * CHANGE TO DIRECTORY
- X */
- X
- X/* Goto a directory */
- LOCAL int changedir()
- X{
- X static char pattern[PATLEN] = { '\0' };
- X char input[PATLEN];
- X dlist *dp;
- X int c, path, found;
- X
- X who = "CHANGE DIRECTORY";
- X /* Get directory name to change to */
- X puthelp("%s: Give directory name (CR:next %s)", who, pattern[0] ? pattern : "quit");
- X c = putecho("Change to:");
- X if((c = getline(input, sizeof(input), c, 0, NULL, CLIST, 0)) < RV_NUL)
- X return(c);
- X else if(c == RV_NUL) {
- X if(pattern[0] == '\0')
- X return(c);
- X }
- X else
- X (void) strcpy(pattern, input);
- X
- X /* Search for directory in tree */
- X found = -1;
- X path = strchr(pattern, '/') != NULL;
- X for(dp = (dlist *) CNEXT; dp; dp = (dlist *) DNEXT(dp))
- X if(match(path ? DPNAM(dp) : DFNAM(dp), pattern) > 0) {
- X found = DDNUM(dp);
- X break;
- X }
- X if(found < 0)
- X for(dp = droot; dp && DDNUM(dp) <= CDNUM; dp = (dlist *) DNEXT(dp))
- X if(match(path ? DPNAM(dp) : DFNAM(dp), pattern) > 0) {
- X found = DDNUM(dp);
- X break;
- X }
- X
- X if(found < 0) { /* Not found */
- X puthelp("%s %s", hitkey, who);
- X return(errequest(pattern, "Not found"));
- X }
- X
- X if(CDNUM == found) /* Found */
- X return(RV_OK);
- X else if(CDNUM > found) /* Position to directory in tree */
- X while(CDNUM > found)
- X (void) gotree(-1);
- X else
- X while(CDNUM < found)
- X (void) gotree(1);
- X
- X return(RV_OK);
- X
- X} /* changedir() */
- X
- X/*
- X * LIST FILES IN TREE
- X */
- X
- X/* List matching/tagged files in tree */
- LOCAL int listtree(t)
- X register int t;
- X{
- X char pat[PATLEN];
- X register dlist *dp;
- X register int c, f, ff, l;
- X
- X who = t ? "LIST TAGGED FILES" : "LIST FILES";
- X if(t && checktagged() == 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No tagged files found"));
- X }
- X else if((c = checktree(mustup)) != RV_OK)
- X return(c);
- X
- X if( !t) {
- 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 }
- X
- X /* Show all matching files */
- X dp = cdlist;
- X l = firstline;
- X ff = 0;
- X c = RV_OK;
- X do {
- X if( !DCANC(dp))
- X continue;
- X else if(DFLAG(dp) != FL_FIL && (c = newflist(dp)) != RV_OK)
- X return(c);
- X for(f = 0; f < DNFIL(dp); f++)
- X if((t && ISTAG(dp, f)) || umatch(dp, f, pat) > 0) {
- X if(l == firstline) {
- X if(ff > 0) {
- X if(t)
- X puthelp("%s (CR:continue ELSE:quit)", who);
- X else
- 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 else
- X c = RV_OK;
- X }
- X treeflag = SF_FULL;
- X clearwindow(firstline, lastline);
- X }
- X ++ff;
- X (void) putfxy(0, l, 0, "%s", pathname(FFNAM(dp, f), DPNAM(dp)));
- X if(++l > lastline)
- X l = firstline;
- X }
- X } while(c == RV_OK && (dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X
- X if(c >= RV_NUL) {
- X puthelp("%s %s", who, hitkey);
- X if(t)
- X (void) putecho("Listed %d tagged file(s)", ff);
- X else
- X (void) putecho("Listed %d file(s) matching %s", ff, pat);
- X c = hitakey(NULL);
- X }
- X return(c);
- X
- X} /* listtree() */
- X
- X/*
- X * CREATE A DIRECTORY
- X */
- X
- X/* Create a directory */
- LOCAL int makedir()
- X{
- X char newname[NAMELEN], buf[EXECLEN];
- X register dlist *dp;
- X register int c, i;
- X
- X who = "MAKE DIRECTORY";
- X if( !CCANC) { /* Cannot change to directory */
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "Cannot make directory"));
- X }
- X
- X puthelp("%s: Give directory name (CR:quit)", who);
- X c = putecho("Make directory:");
- X if((c = getline(newname, sizeof(newname), c, 0, NULL, GNULL, 0)) != RV_OK)
- X return(c);
- X
- X puthelp("%s %s", who, hitkey);
- X if(strchr(newname, '/') || EQU(newname, ".") || EQU(newname, ".."))
- X return(errequest(newname, "Cannot make directory"));
- X for(i = 0; i < CNFIL; i++)
- X if(EQU(FFNAM(cdlist, i), newname))
- X return(errequest(newname, "Already exists"));
- X
- X /* Build command line and call mkdir program */
- X (void) sprintf(buf, "%s %s", MKDIR, pathname(newname, CPNAM));
- X if(callsystem(buf, 0, 0) != RV_OK)
- X return(errequest(newname, "Error in creating"));
- X
- X /* Insert new directory into tree and file lists */
- X dp = newdlist(newname, FL_FIL);
- X c = newflist(cdlist);
- X
- X /* Update flag and return */
- X if(dp) {
- X treeflag = SF_FULL;
- X return(c);
- X }
- X return(RV_NUL);
- X
- X} /* makedir() */
- X
- X/*
- X * REMOVE A DIRECTORY OR TREE
- X */
- X
- X/* Remove a directory */
- LOCAL int removedir()
- X{
- X char buf[EXECLEN];
- X register dlist *dp;
- X register int c, i, rflag;
- X
- X who = "REMOVE DIRECTORY";
- X /* Check if removing is permitted */
- X if( !CCANC || cdlist == droot || CNDIR > 0) {
- X puthelp("%s %s", who, hitkey);
- X if( !CCANC) /* Cannot change to directory */
- X return(errequest(CFNAM, "Cannot remove"));
- X else if(cdlist == droot) /* Root cannot be removed */
- X return(errequest(CFNAM, "Cannot remove root directory"));
- X else if(CNDIR > 0) /* Contains subdirectories */
- X return(errequest(CFNAM, "Contains subdirectories. Cannot remove subtrees"));
- X }
- X
- X puthelp("%s (Y:remove ELSE:quit)", who);
- X rflag = 0;
- X (void) putecho("Remove directory %s ?", CFNAM);
- X if((c = hitakey(NULL)) != 'y')
- X return(c);
- X if(CNFIL > 0) {
- X puthelp("%s (Y:request N:don't request ELSE:quit)", who);
- X c = hitakey("Directory is not empty, request before removing files ?", echoline, DA_NONE);
- X if( !(c == 'y' || c == 'n'))
- X return(c);
- X rflag = c == 'y';
- X }
- X
- X /* First remove files from directory */
- X if(rflag)
- X puthelp("REMOVE FILE (Y:remove Q:quit ELSE:don't remove)");
- X else
- X puthelp("%s (In progress ...)", who);
- X for(i = CNFIL - 1; i >= 0; i--) {
- X c = removefile(cdlist, i, rflag);
- X if(c == 'q' || c < RV_NUL)
- X return(c);
- X else if(c == RV_OK && rflag) {
- X showflist(firstfline);
- X (void) putfxy(FCOL, DTROW(cdlist), 0, NFFMT, CNFIL);
- X }
- X }
- X
- X /* There are files: cannot remove directory */
- X if(CNFIL > 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "Is not empty"));
- X }
- X
- X if(rflag) { /* Request before removing */
- X puthelp("%s (Y:remove ELSE:quit)", who);
- X (void) putecho("Remove directory %s ?", CFNAM);
- X if((c = hitakey(NULL)) != 'y')
- X return(c);
- X }
- X (void) changelist(droot, NULL);
- X (void) sprintf(buf, "%s %s", RMDIR, CPNAM);
- X if(callsystem(buf, 0, 0) != RV_OK) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "Error in removing"));
- X }
- X
- X /* Get new top directory on screen and current directory */
- X for(dp = cdlist; dp && DTROW(dp) <= lastdline; dp = (dlist *) DNEXT(dp))
- X ;
- X if(cdlist == tdlist || (tdlist != droot && dp == DNULL)) {
- X tdlist = (dlist *) DPREV(tdlist);
- X c = 1;
- X }
- X else {
- X tdlast = DNULL;
- X c = 0;
- X }
- X cdlist = (dlist *) CPREV;
- X
- X /* Delete directory list entry */
- X deletedlist(CNEXT);
- X
- X /* Update flags */
- X treeflag = SF_FULL;
- X writeflag = 1;
- X return(RV_OK);
- X
- X} /* removedir() */
- X
- X/*
- X * BUILD SUBDIRECTORY TREE
- X */
- X
- X/* Scan current directory for subdirs and build up and insert subtree */
- LOCAL int buildtree()
- X{
- X char inp[5], name[NAMELEN];
- X register dlist *np, *dp, *p;
- X register int lev, f, n;
- X
- X who = "BUILD TREE";
- X /* Check if current directory already contains subdirectories */
- X if((p = (dlist *) CNEXT) && DLEVL(p) > CLEVL) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "Contains subdirectories"));
- X }
- X /* Check if there is any directory to build */
- X for(f = 0; f < CNFIL; f++)
- X if(FMODE(cdlist, f) == FF_DIR)
- X break;
- X if(f >= CNFIL) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(CFNAM, "No subdirectories found"));
- X }
- X
- X /* Get max level to build up the subtree */
- X puthelp("%s: Give max tree level (CR:quit)", who, CFNAM);
- X n = putecho("Give level:");
- X n = getline(inp, sizeof(inp), n, 0, NULL, GNULL, 0);
- X if(n != RV_OK || (lev = atoi(inp)) <= 0)
- X return(n);
- X
- X /* Preserve next dlist and open dlist chain for buildread() */
- X np = (dlist *) CNEXT;
- X CNEXT = GNULL;
- X n = dircount;
- X
- X /* Build up the tree for all files which are directories */
- X for(f = 0; f < CNFIL; f++)
- X if(FMODE(cdlist, f) == FF_DIR) {
- X (void) strcpy(name, pathname(FFNAM(cdlist, f), CPNAM));
- X puthelp("%s: Building %s %s", FFNAM(cdlist, f), who, cancel);
- X if(buildread(name, CLEVL+1, CLEVL+lev, 1) == RV_INT)
- X break;
- X }
- X n = dircount - n;
- X
- X if(n > 0) {
- X /* Search for last new dlist, update dlist numbers and close dlist chain */
- X dp = cdlist;
- X f = CDNUM;
- X do
- X DDNUM(dp) = f++;
- X while(DNEXT(dp) && (dp = (dlist *) DNEXT(dp)));
- X DNEXT(dp) = (glist *) np; /* Close the chain */
- X if(np)
- X DPREV(np) = (glist *) dp;
- X for(dp = np; dp; dp = (dlist *) DNEXT(dp), f++)
- X DDNUM(dp) = f;
- X infodlist(); /* Rebuild treeinfo */
- X checkindent(); /* Check indention */
- X treeflag = SF_FULL;
- X bell(VARSET(V_BL));
- X puthelp("%s %s", who, hitkey);
- X (void) putecho("%d new directories built and inserted", n);
- X }
- X else {
- X /* No new directories found and inserted, close dlist chain */
- X CNEXT = (glist *) np;
- X bell(VARSET(V_BL));
- X puthelp("%s %s", who, hitkey);
- X (void) putecho("No new directories built or inserted");
- X }
- X return(hitakey(NULL));
- X
- X} /* buildtree() */
- X
- X/*
- X * UPDATE ALL FILE LISTS
- X */
- X
- X/* Scan directory tree and update all file lists not yet read in or changed */
- LOCAL int scantree(f)
- X register int f;
- X{
- X register dlist *dp;
- X register int c;
- X
- X who = "UPDATE TREE";
- X if(f && (c = checktree("Update tree ?")) != RV_OK)
- X return(c);
- X
- X /* Walk thru directory list and update file lists if needed */
- X if(buildflag) {
- X puthelp("%s %s", who, cancel);
- X dp = cdlist;
- X do {
- X if(keypressed() && hitakey(NULL) < RV_NUL)
- X break;
- X if( !DCANC(dp)) { /* Cannot cd: skip */
- X DFLAG(dp) = FL_FIL;
- X continue;
- X }
- X else if(DFLAG(dp) != FL_FIL) { /* Rebuild file list */
- X if((c = newflist(dp)) != RV_OK)
- X return(c);
- X showdline(dp);
- X flushout();
- X treeflag |= SF_MOVE|SF_ECHO;
- X }
- X } while((dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X }
- X
- X return(RV_OK);
- X
- X} /* scantree() */
- X
- X/*
- X * SORT FILELISTS IN TREE
- X */
- X
- X/* Sort filelists in current directory or subtree */
- LOCAL int sorttree(t)
- X register int t;
- X{
- X register dlist *dp;
- X register int s;
- X
- X who = t ? "SORT TREE" : "SORT DIRECTORY";
- X s = CSORT ? 0 : 1; /* Toggle sort flag */
- X
- X /* Walk thru subtree */
- X puthelp("%s %s", who, cancel);
- X if(t) {
- X for(dp = (dlist *) CNEXT; dp && DLEVL(dp) > CLEVL; dp = (dlist *) DNEXT(dp)) {
- X if(keypressed() && hitakey(NULL) < RV_NUL)
- X return(RV_NUL);
- X (void) sortlist(dp, s);
- X }
- X }
- X if((s = sortlist(cdlist, s)) == RV_OK)
- X treeflag |= SF_FILE;
- X
- X return(s);
- X
- X} /* sorttree() */
- X
- X/*
- X * ZOOM FILELISTS IN TREE
- X */
- X
- X/* Get zoom pattern and rebuild filelists in directory or subtree */
- LOCAL int zoomtree(t)
- X register int t;
- X{
- X char pat[PATLEN];
- X register dlist *dp;
- X register int c;
- X
- X who = t ? "ZOOM TREE" : "ZOOM DIRECTORY";
- X puthelp("%s: Give file pattern (CR:all files)", who);
- X if((c = getpattern(pat, "Zoom which files:")) < RV_NUL)
- X return(c);
- X
- X /* Walk thru subtree */
- X puthelp("%s %s", who, cancel);
- X dp = cdlist;
- X do {
- X if(keypressed() && hitakey(NULL) < RV_NUL)
- X break;
- X if(zoomlist(dp, pat)) {
- X showdline(dp);
- X flushout();
- X }
- X } while(t && (dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > CLEVL);
- X
- X treeflag |= SF_FILE|SF_LIST;
- X return(RV_OK);
- X
- X} /* zoomtree() */
- X
- X/*
- X * MARKED AND TAGGED DIRECTORIES
- X */
- X
- X/* Set/unset mark on current directory */
- LOCAL VOID markdir(f)
- X register int f;
- X{
- X if(mdlist == cdlist && !f) /* Reset mark */
- X mdlist = DNULL;
- X else /* Set mark */
- X mdlist = cdlist;
- X
- X} /* markdir() */
- X
- X/* Go to marked directory */
- LOCAL int gomarkdir()
- X{
- X register dlist *mp, *dp;
- X
- X if(mdlist) {
- X mp = mdlist;
- X mdlist = cdlist;
- X for(dp = cdlist; dp; dp = (dlist *) DNEXT(dp)) /* Search forward */
- X if(dp == mp) {
- X while(cdlist != mp && gotree(1))
- X ;
- X return(1);
- X }
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp)) /* Search backward */
- X if(dp == mp) {
- X while(cdlist != mp && gotree(-1))
- X ;
- X return(1);
- X }
- X }
- X
- X return(0); /* No mark set */
- X
- X} /* gomarkdir() */
- X
- X/* Goto directory containing tagged files */
- LOCAL int gotagged()
- X{
- X register dlist *dp;
- X
- X for(dp = (dlist *) DNEXT(cdlist); dp; dp = (dlist *) DNEXT(dp))
- X if(DNTAG(dp)) {
- X while(gotree(1) && dp != cdlist)
- X ;
- X return(1);
- X }
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp)) /* Search backward */
- X if(DNTAG(dp)) {
- X if(dp != cdlist)
- X while(gotree(-1) && dp != cdlist)
- X ;
- X return(1);
- X }
- X
- X return(0); /* No match */
- X
- X} /* gotagged() */
- X
- X/* Goto parent directory */
- LOCAL int goparent()
- X{
- X register int lev;
- X
- X if(cdlist != droot) {
- X lev = CLEVL - 1;
- X while(gotree(-1) && CLEVL != lev)
- X ;
- X return(1);
- X }
- X return(0);
- X
- X} /* goparent() */
- X
- X/*
- X * SEARCH FOR PATTERN IN TREE
- X */
- X
- X/* Search for pattern in tree */
- LOCAL int greptree(t)
- X register int t;
- X{
- X char input[PATLEN];
- X register dlist *dp;
- X register int f, c, ff, nt;
- X
- X who = t ? "GREP TREE" : "GREP DIRECTORY";
- X if(t && (c = checktree(mustup)) != RV_OK)
- X return(c);
- X
- X puthelp("%s: Give search pattern (CR:%s)", who, gpattern[0] ? gpattern : "quit");
- X c = putecho("Search for pattern:");
- 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 puthelp("%s: Give file pattern (CR:all files)", who);
- X if((c = getpattern(input, "Search in which files:")) == RV_NUL)
- X (void) strcpy(input, "*");
- X else if(c != RV_OK)
- X return(c);
- X
- X /* Walk thru subtree */
- X dp = cdlist;
- X do {
- X nt = DNTAG(dp);
- X ff = -1;
- X if(CFLAG != FL_FIL && (c = newflist(cdlist)) != RV_OK) /* Update! */
- X return(c);
- X /* Walk thru file list */
- X for(c = RV_NUL, f = 0; f < CNFIL; f++) {
- X ff = -1;
- X /* Search in all matching files */
- X if((c = umatch(cdlist, f, input)) > 0) {
- X (void) putecho("Search for \'%s\' in %s", gpattern, pathname(FFNAM(cdlist, f), CPNAM));
- X flushout();
- X /* Search pattern found: what to do? */
- X if((c = grepfile(cdlist, f)) == RV_OK) {
- X ff = f;
- X treeflag &= ~(SF_ECHO|SF_HELP);
- X (void) updatetree(0);
- X puthelp("%s (CR:next SP:change dir M:mark dir T:tag file ELSE:quit)", who);
- X (void) putecho("Found \'%s\': %s -> %s", gpattern, FFNAM(cdlist, f), CFNAM);
- X if((c = hitakey(NULL)) == 't') {
- X FITAG(cdlist, f) = FF_TAG;
- X ++CNTAG;
- X c = '\n';
- X }
- X else if(c == 'm') {
- X markdir(1);
- X c = '\n';
- X }
- X else if(c == ' ') {
- X if((c = filemenu(ff, RV_NUL)) == RV_END)
- X return(c);
- X (void) updatetree(0);
- X puthelp("%s (CR:continue SP:select ELSE:quit)", who);
- X (void) putecho("Continue searching for \'%s\':", gpattern);
- X if((c = hitakey(NULL)) == ' ')
- X return(RV_OK);
- X }
- X if(c != '\n')
- X break;
- X }
- X else if(c == RV_INT)
- X break;
- X }
- X }
- X if(nt != DNTAG(dp))
- X showdlist(dp, 0);
- X } while(t && (c == RV_NUL || c == '\n') && gotree(1) && CLEVL > DLEVL(dp));
- X
- X if(c == RV_END)
- X return(c);
- X while(cdlist != dp) /* Position to starting directory */
- X (void) gotree(-1);
- X
- X if(ff < 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(gpattern, "Not found"));
- X }
- X else
- X return(RV_OK);
- X
- X} /* greptree() */
- X
- X/*
- X * FIND A FILE IN TREE
- X */
- X
- X/* Find a file in file tree */
- LOCAL int findtree(t)
- X register int t;
- X{
- X char input[PATLEN];
- X register dlist *dp;
- X register int f, c, ff, nt;
- X
- X who = t ? "FIND TREE" : "FIND DIRECTORY";
- X if(t && (c = checktree(mustup)) != RV_OK)
- X return(c);
- X
- X puthelp("%s: Give file pattern (CR:%s)", who, fpattern[0] ? fpattern : "quit");
- X if((c = getpattern(input, "Search for 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 /* Walk thru subtree */
- X dp = cdlist;
- X do {
- X nt = DNTAG(dp);
- X ff = -1;
- X if(CFLAG != FL_FIL && (c = newflist(cdlist)) != RV_OK) /* Update! */
- X return(c);
- X (void) putecho("Find \'%s\' in %s", fpattern, CPNAM);
- X flushout();
- X /* Walk thru file list */
- X for(c = RV_NUL, f = 0; f < CNFIL; f++) {
- X ff = -1;
- X /* File found: what to do now? */
- X if((c = findfile(cdlist, f)) == RV_OK) {
- X ff = f;
- X treeflag &= ~(SF_ECHO|SF_HELP);
- X (void) updatetree(0);
- X puthelp("%s (CR:next SP:change dir M:mark dir T:tag file ELSE:quit)", who);
- X (void) putecho("Found: %s -> %s", FFNAM(cdlist, f), CFNAM);
- X if((c = hitakey(NULL)) == 't') {
- X FITAG(cdlist, f) = FF_TAG;
- X ++CNTAG;
- X c = '\n';
- X }
- X else if(c == 'm') {
- X markdir(1);
- X c = '\n';
- X }
- X else if(c == ' ') {
- X if((c = filemenu(ff, RV_NUL)) == RV_END)
- X return(c);
- X (void) updatetree(0);
- X puthelp("%s (CR:continue SP:select ELSE:quit)", who);
- X (void) putecho("Continue searching file \'%s\':", fpattern);
- X if((c = hitakey(NULL)) == ' ')
- X return(RV_OK);
- X }
- X if(c != '\n')
- X break;
- X }
- X }
- X if(nt != DNTAG(dp))
- X showdlist(dp, 0);
- X } while(t && (c == RV_NUL || c == '\n') && gotree(1) && CLEVL > DLEVL(dp));
- X
- X if(c == RV_END)
- X return(c);
- X while(cdlist != dp) /* Position to starting directory */
- X (void) gotree(-1);
- X
- X if(ff < 0) {
- X puthelp("%s %s", who, hitkey);
- X return(errequest(fpattern, "Not found"));
- X }
- X else
- X return(RV_OK);
- X
- X} /* findtree() */
- X
- X/*
- X * WRITE TREE LIST
- X */
- X
- X/* Write tree list */
- LOCAL int writetreelist()
- X{
- X char list[INPLEN], name[NAMELEN], pat[PATLEN];
- X register char *fn, *w;
- X register int c, wc;
- X
- X who = "WRITE TREE";
- X if((c = changelist(cdlist, who)) < RV_NUL)
- X return(c);
- X puthelp("%s: Give list filename (CR:quit)", who);
- X c = putecho("Write list to:");
- X if((c = getline(list, sizeof(list), c, 0, NULL, CLIST, 1)) != RV_OK)
- X return(c);
- X puthelp("%s: Give choice (D:dirs F:files L:list M:matches T:tags ELSE:quit)", who);
- X (void) putecho("Write out what:");
- X switch(c = hitakey(NULL)) {
- X default: return(c);
- X case 'D':
- X case 'd':
- X wc = 'd';
- X w = "Directory";
- X break;
- X case 'F':
- X case 'f':
- X wc = 'f';
- X w = "File";
- X break;
- X case 'L':
- X case 'l':
- X wc = 'l';
- X w = "Tree";
- X break;
- X case 'T':
- X case 't':
- X wc = 't';
- X w = "Tagged file";
- X break;
- X case 'M':
- X case 'm':
- X puthelp("WRITE MATCHING FILES: Give file pattern (CR:quit)");
- X if((c = getpattern(pat, "Write which files:")) < RV_NUL)
- X return(c);
- X wc = 'm';
- X w = pat;
- X break;
- X }
- X
- X /* Write out list file */
- X puthelp("%s %s", who, hitkey);
- X if(fn = writedlist(list, cdlist, w, wc)) {
- X (void) strcpy(name, fn);
- X checkdlist(name);
- X if(buildflag) {
- X if((c = updatedlist()) != RV_OK)
- X return(c);
- X treeflag |= SF_FILE;
- X }
- X if(wc == 'm')
- X (void) putecho("Files matching \'%s\' written to \'%s\'", w, name);
- X else
- X (void) putecho("%s list written to \'%s\'", w, name);
- X return(hitakey(NULL));
- X }
- X /* Error in writing */
- X return(errequest(list, "Cannot write"));
- X
- X} /* writetreelist() */
- X
- X/*
- X * MOVE UP OR DOWN IN DIRECTORY TREE
- X */
- X
- X/* Go up or down in directory list */
- GLOBL int gotree(dir)
- X register int dir;
- X{
- X register int i;
- X
- X /* At beginning or end of directory tree */
- X if((dir < 0 && CPREV == GNULL) || (dir > 0 && CNEXT == GNULL))
- X return(0);
- X if(dir < 0) { /* Previous directory in tree */
- X cdlist = (dlist *) CPREV;
- X treeflag |= SF_LIST;
- X /* Out of screen boundaries */
- X if(DTROW(cdlist) <= firstdline && cdlist != droot) {
- X tdlist = cdlist;
- X for(i = ndlines / 2; i > 0 && DPREV(tdlist); i--)
- X tdlist = (dlist *) DPREV(tdlist);
- X treeflag |= SF_TREE;
- X }
- X else
- X treeflag |= SF_LAST;
- X }
- X else { /* Next directory in tree */
- X cdlist = (dlist *) CNEXT;
- X treeflag |= SF_LIST;
- X /* Out of screen boundaries */
- X if(DTROW(cdlist) > lastdline || (DTROW(cdlist) == lastdline && CNEXT)) {
- X tdlist = cdlist;
- X for(i = ndlines / 2; i > 0 && DNEXT(tdlist); i--)
- X tdlist = (dlist *) DNEXT(tdlist);
- X for(i = ndlines; DPREV(tdlist) && i > 0; i--)
- X tdlist = (dlist *) DPREV(tdlist);
- X treeflag |= SF_TREE;
- X }
- X else
- X treeflag |= SF_LAST;
- X }
- X
- X treeflag |= SF_FILE;
- X return(1);
- X
- X} /* gotree() */
- X
- X/* Go up or down on same level */
- LOCAL int golevel(dir)
- X register int dir;
- X{
- X register dlist *dp;
- X register int l;
- X
- X l = CLEVL;
- X if(dir < 0 && cdlist != droot) { /* Up */
- X for(dp = (dlist *) CPREV; dp; dp = (dlist *) DPREV(dp))
- X if(DLEVL(dp) <= l)
- X break;
- X do
- X (void) gotree(dir);
- X while(dp && cdlist != dp);
- X if(dp && DLEVL(dp) == l)
- X return(1);
- X }
- X else if(dir > 0 && CNEXT) { /* Down */
- X for(dp = (dlist *) CNEXT; dp; dp = (dlist *) DNEXT(dp))
- X if(DLEVL(dp) <= l)
- X break;
- X do
- X (void) gotree(dir);
- X while(dp && cdlist != dp);
- X if(dp && DLEVL(dp) == l)
- X return(1);
- X }
- X
- X return(0); /* Not possible */
- X
- X} /* golevel() */
- X
- X/* Go page up or down */
- LOCAL int gopage(dir)
- X register int dir;
- X{
- X register int l;
- X
- X if(dir < 0 && CPREV) { /* Page up */
- X for(l = ndlines; l > 0 && gotree(dir); l--)
- X ;
- X return(1);
- X }
- X else if(dir > 0 && CNEXT) { /* Page down */
- X for(l = ndlines; l > 0 && gotree(1) ; l--)
- X ;
- X return(1);
- X }
- X
- X return(0); /* Not possible */
- X
- X} /* gopage() */
- X
- X/* Go to beginning or end of tree */
- LOCAL int gobegend(dir)
- X register int dir;
- X{
- X if(dir < 0 && CPREV) { /* Beginning */
- X mdlist = cdlist;
- X while(gotree(dir))
- X ;
- X return(1);
- X }
- X else if(dir > 0 && CNEXT) { /* End */
- X mdlist = cdlist;
- X while(gotree(dir))
- X ;
- X return(1);
- X }
- X
- X return(0); /* Not possible */
- X
- X} /* gobegend() */
- X
- X/*
- X * REFRESH ON SCREEN RESIZING
- X */
- X
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X/* Refresh tree screen after screen size changes */
- GLOBL int refreshtree(f)
- X register int f;
- X{
- X register dlist *dp;
- X
- X if(f)
- X (void) refreshfile(0);
- X checkindent();
- X ndlines = lastdline - firstdline;
- X dp = cdlist;
- X cdlist = tdlist = droot;
- X while(cdlist != dp && gotree(1))
- X ;
- X treeflag = SF_FULL;
- X return(RV_OK);
- X
- X} /* refreshtree() */
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X
- X/*
- X * SELECT DIRECTORY
- X */
- X
- X/* Walk thru tree and select a directory */
- GLOBL char *selectdir(what)
- X register char *what;
- X{
- X register dlist *cd, *td;
- X register char *dn;
- X register int c, f;
- X
- X /* Save current and top dirs */
- X cd = cdlist;
- X td = tdlist;
- X dn = what;
- X treeflag = SF_FULL;
- X
- X /* Select tree loop */
- X do {
- X /* Special update for tree screen if needed */
- X if(treeflag) {
- X f = 0;
- X if(treeflag & SF_HELP)
- X f |= SF_HELP;
- X if(treeflag & SF_ECHO)
- X f |= SF_ECHO;
- X if((c = updatetree(1)) != RV_OK) {
- X dn = NULL;
- X break;
- X }
- X if(f & SF_HELP)
- X puthelp("SELECT DIRECTORY (CR:select Q:quit)");
- X if(f & SF_ECHO)
- X (void) putecho("Move to and select directory for %s", what);
- X if(f)
- X (void) cursorxy(TCOL+DTCOL(cdlist)-1, DTROW(cdlist));
- X f = 0;
- X }
- X switch(c = getkey()) {
- X default: /* Ignore */
- X bell(VARSET(V_BL));
- X break;
- X case '>': /* Select current directory */
- X case ' ':
- X case K_SEL:
- X case K_INS:
- X dn = CPNAM;
- X break;
- X case '<': /* Parent */
- X case K_DEL:
- X if( !goparent())
- X bell(VARSET(V_BL));
- X break;
- X case 'q': /* Return */
- X case 'Q':
- X case K_BRK:
- X case K_EOF: /* EOF */
- X dn = NULL;
- X break;
- X case K_PREV: /* Previous */
- X case 'k': /* For vi fans */
- X if( !gotree(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_NEXT: /* Next */
- X case 'j': /* For vi fans */
- X if( !gotree(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_BACK: /* Up on same level */
- X if( !golevel(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_FORW: /* Down on same level */
- X if( !golevel(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_PPAG: /* Page up */
- X if( !gopage(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_NPAG: /* Page down */
- X if( !gopage(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_HOME: /* Beginning */
- X if( !gobegend(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_END: /* End */
- X if( !gobegend(1))
- X bell(VARSET(V_BL));
- X break;
- X case 'c': /* Change to directory */
- X c = changedir();
- X break;
- X case '@': /* Mark current directory */
- X case K_MARK:
- X markdir(0);
- X break;
- X case '#': /* Goto previously marked directory */
- X case K_GOTO:
- X if( !gomarkdir())
- X bell(VARSET(V_BL));
- X break;
- X case K_SIZE: /* Screen size changed */
- X c = RV_SIZ;
- X /*FALL THROUGH*/
- X case K_REFR: /* Refresh */
- X treeflag = SF_FULL;
- X break;
- X }
- X#if defined(SIGWINCH) && defined(TIOCGWINSZ)
- X /* Refresh screen after screen resize */
- X if(c == RV_SIZ)
- X (void) refreshtree(1);
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X } while(dn == what);
- X
- X /* Restore current and top dirs */
- X cdlist = cd;
- X tdlist = td;
- X
- X return(dn);
- X
- X} /* selectdir() */
- X
- X/*
- X * DIRECTORY TREE MENU LOOP
- X */
- X
- X/* Tree menu */
- GLOBL int treemenu(update)
- X register int update;
- X{
- X register int c;
- X
- X /* Init tree variables */
- X checkindent();
- X cdlist = tdlist = droot;
- X menuline = tmline;
- X treeflag = SF_FULL;
- X
- X /* Scan and update file lists in tree if reading from a list file */
- X if(update && scantree(0) != RV_OK)
- X return(c);
- X
- X /* Tree menu loop */
- X do {
- X /* Update tree screen if needed and clock */
- X buildflag = 0;
- X if(treeflag && (c = updatetree(0)) != RV_OK)
- X return(c);
- X#ifdef UTCLOCK
- X if(VARSET(V_CL))
- X clockon();
- X#endif /* UTCLOCK */
- X c = getkey();
- X#ifdef UTCLOCK
- X if(VARSET(V_CL))
- X clockoff();
- X#endif /* UTCLOCK */
- X switch(c) {
- X case K_BRK: /* Ignore interrupt */
- X default: /* Unknown: ring the bell */
- X bell(VARSET(V_BL));
- X break;
- X case K_PREV: /* Previous */
- X case 'k': /* For vi fans */
- X if( !gotree(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_NEXT: /* Next */
- X case 'j': /* For vi fans */
- X if( !gotree(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_BACK: /* Up on same level */
- X if( !golevel(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_FORW: /* Down on same level */
- X if( !golevel(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_TAG: /* Next directory containing tagged files */
- X if( !gotagged())
- X bell(VARSET(V_BL));
- X break;
- X case K_UP: /* Scroll up */
- X if( !scrolltree(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_DOWN: /* Scroll down */
- X if( !scrolltree(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_PPAG: /* Page up */
- X if( !gopage(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_NPAG: /* Page down */
- X if( !gopage(1))
- X bell(VARSET(V_BL));
- X break;
- X case K_HOME: /* Begin */
- X if( !gobegend(-1))
- X bell(VARSET(V_BL));
- X break;
- X case K_END: /* End */
- X if( !gobegend(1))
- X bell(VARSET(V_BL));
- X break;
- X case '@': /* Mark current directory */
- X case K_MARK:
- X markdir(0);
- X break;
- X case '#': /* Goto previously marked directory */
- X case K_GOTO:
- X if( !gomarkdir())
- X bell(VARSET(V_BL));
- X break;
- X case K_SIZE: /* Screen size changed */
- X c = RV_SIZ;
- X /*FALL THROUGH*/
- X case K_REFR: /* Refresh */
- X treeflag = SF_FULL;
- X break;
- X case '?': /* Help */
- X case 'h':
- X case 'H':
- X case K_HELP:
- X c = showhelp('t');
- X break;
- X case '<': /* Change to parent */
- X case K_DEL:
- X if( !goparent()) {
- X bell(VARSET(V_BL));
- X break;
- X }
- X /*FALL THROUGH*/
- X case ' ': /* Change to directory */
- X case '>':
- X case K_SEL:
- X case K_INS:
- X do
- X c = filemenu(-1, c);
- X while(c == RV_DIR);
- X break;
- X case 'b': /* Backup tree */
- X c = backupdir(ONTG(c));
- X break;
- X case 'l': /* List file in tree */
- X c = listtree(ONTG(c));
- X break;
- X case 'm': /* Create a directory */
- X c = makedir();
- X break;
- X case 'r': /* Remove a directory */
- X c = removedir();
- X break;
- X case 'c': /* Change to directory */
- X c = changedir();
- X break;
- X case 'L': /* List tagged files */
- X c = listtree(ONTG(c));
- X break;
- X case 'B': /* Backup tagged files */
- X c = backupdir(ONTG(c));
- X break;
- X case 'C': /* Copy tagged files */
- X c = copytagged();
- X break;
- X case 'R': /* Remove tagged files */
- X c = removetagged();
- X break;
- X case 'M': /* Move tagged files */
- X c = movetagged();
- X break;
- X case 's': /* Display directory status info */
- X case 'S':
- X c = statusdir();
- X break;
- X case 'i': /* Display directory information */
- X case 'I':
- X c = infodir();
- X break;
- X case 'g': /* Search for string */
- X case 'G':
- X c = greptree(ONTR(c));
- X break;
- X case 'f': /* Find a file */
- X case 'F':
- X c = findtree(ONTR(c));
- X break;
- X case 't': /* Tag files */
- X case 'T':
- X c = tagtree(ONTR(c));
- X break;
- X case 'u': /* Untag files */
- X case 'U':
- X c = untagtree(ONTR(c));
- X break;
- X case 'n': /* New sort file list */
- X case 'N':
- X c = sorttree(ONTR(c));
- X break;
- X case 'z': /* Zoom file list */
- X case 'Z':
- X c = zoomtree(ONTR(c));
- X break;
- X case '0': /* Switch menu line */
- X menuline = menuline == utreemenu ? tmline : utreemenu;
- X treeflag |= SF_HELP;
- X break;
- X case '1': /* User defined tree command 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 if(changelist(cdlist, "USER COMMAND") < RV_NUL)
- X break;
- X c = usercommand(c - '0' + V_TC0);
- X break;
- X case '!': /* Escape to shell */
- X case '$':
- X if(changelist(cdlist, "SHELL ESCAPE") < RV_NUL)
- X break;
- X c = history(c, V_TC1);
- X if(VARSET(V_ST))
- X (void) scandlist(droot);
- X if(buildflag)
- X c = updatedlist();
- 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 '+': /* Enlarge tree window */
- X if( !resizetree(1))
- X bell(VARSET(V_BL));
- X break;
- X case '-': /* Shrink tree window */
- X if( !resizetree(-1))
- X bell(VARSET(V_BL));
- X break;
- X case 'o': /* Write out tree list */
- X case 'O':
- X c = writetreelist();
- X break;
- X case '/': /* Scan directory tree and update file lists */
- X c = scantree(1);
- X break;
- X case '\\': /* Build subdirectory tree */
- X c = buildtree();
- X break;
- X case 'a': /* Display version string */
- X case 'A':
- X c = putversion(echoline, "ABOUT: Utree version");
- X break;
- X case 'd': /* Date */
- X case 'D':
- X c = printdate();
- X break;
- X case 'w': /* Print current working directory */
- X case 'W':
- X c = printcwd();
- X break;
- X case 'q': /* Exit utree */
- X case 'Q':
- X case K_EOF:
- 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 = refreshtree(1);
- X#endif /* SIGWINCH && TIOCGWINSZ */
- X } while( !(c == RV_END || c == RV_ERR));
- X
- X return(c);
- X
- X} /* treemenu() */
- X
- END_OF_FILE
- if test 63122 -ne `wc -c <'src/tree.c'`; then
- echo shar: \"'src/tree.c'\" unpacked with wrong size!
- fi
- # end of 'src/tree.c'
- fi
- echo shar: End of archive 8 \(of 8\).
- cp /dev/null ark8isdone
- 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
-