home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-09-08 | 69.7 KB | 2,176 lines |
- Newsgroups: comp.sources.unix
- Path: sparky!uunet!decwrl!deccrl!news.crl.dec.com!pa.dec.com!vixie
- From: klin@iat.uni-paderborn.de (Peter Klingebiel)
- Subject: v26i068: utree - screen oriented filesystem utility (V3.03b-um), Part05/08
- Message-ID: <1992Sep7.214926.26985@PA.dec.com>
- Originator: vixie@cognition.pa.dec.com
- Sender: unix-sources-moderator@pa.dec.com
- Organization: DEC Palo Alto
- Date: Mon, 7 Sep 92 21:49:26 GMT
- Approved: vixie@pa.dec.com
- Lines: 2163
-
- Submitted-By: klin@iat.uni-paderborn.de (Peter Klingebiel)
- Posting-Number: Volume 26, Issue 68
- Archive-Name: utree/part05
-
- #! /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 5 (of 8)."
- # Contents: lib/utree.help src/list.c src/vars.c
- # Wrapped by vixie@cognition.pa.dec.com on Mon Sep 7 14:39:56 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'lib/utree.help' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'lib/utree.help'\"
- else
- echo shar: Extracting \"'lib/utree.help'\" \(22386 characters\)
- sed "s/^X//" >'lib/utree.help' <<'END_OF_FILE'
- X#
- X# UTREE.HELP
- X# UTREE help pages
- X# 3.03-um klin, Sun Feb 23 18:45:19 1992
- X# Directory: /usr/local/lib (default)
- X#
- X# Copyright (c) 1991/92 by Peter Klingebiel & UNIX Magazin Muenchen.
- X# For copying and distribution information see the file COPYRIGHT.
- X#
- X# Help about items is enclosed in two lines '#@item' and '#@'.
- X# The string 'item' is used as item for the menuline, the lines
- X# between these opening and closing lines are the help lines
- X# for the topic 'item'. The upper case character in 'item' is used
- X# as hotkey for selecting help about this topic.
- X# Be sure that all items separated by a blank fit in one screen line!
- X# Don't change the hot keys because they are hard coded in utree!
- X#
- X# SCCSID=@(#) utree 3.03-um (klin) Feb 23 1992 lib/utree.help
- X
- X#@Help h: About help
- X
- X The utree help page menu lets you select help pages about the
- X following topics (menu hotkeys are enclosed in brackets):
- X
- X (h) Help This help page.
- X (a) About About utree and some naming conventions.
- X (u) Usage Utree usage and command line options.
- X (g) Global Global commands for tree and file screen.
- X (t) Tree Commands for the tree screen.
- X (f) File Commands for the file screen.
- X (e) Edit Commands for the builtin line editor.
- X (v) Vars Utree variables and variable definition.
- X (c) Cmds Filetype dependent command definition.
- X (l) Line Line format for tree, file and filetype commands.
- X (k) Keys Function keys used by utree.
- X (p) Patterns File and time pattern matching.
- X#@
- X#@About a: About utree and key naming conventions
- X
- X This is utree 3.03-um, a screen oriented filesystem browser.
- X
- X Copyright (c) 1991/92 Peter Klingebiel & UNIX Magazin.
- X All rights reserved.
- X
- X First utree version (utree 1.00) created in July 1988.
- X
- X The naming conventions for keys in the help pages are:
- X 'C-key' means hold the <CONTROL>-key and hit <key>,
- X 'key' means a single keystroke on the key <key>.
- X
- X For many commands on tree and file screen case is significant.
- X Commands given in lowercase letters work on the current directory
- X or file, commands given in uppercase letters work on the current
- X subtree or on tagged files in current subtree or directory.
- X
- X Many function keys are supported by utree, i.e the four cursor
- X keys, the begin and end key and some others. For more information
- X about default key bindings and user definable keybindings see
- X the keys help page.
- X#@
- X#@Usage u: About utree usage and command line options
- X
- X Usage: utree [-LSVabcghnrqstuw] [-d var=[val]] [-d typ:[cmd]]
- X [-f lst] [-i ind] [-l lev] [-p lin] [-v mod] [-x cmd]
- X [rootdir]
- X
- X The meaning of the command line options is:
- X
- X -L Follow symbolic links.
- X -S Ignore default minimal screen size.
- X -V Display program version.
- X -a Read in all (including hidden) directories.
- X -b Suppress ringing of the bell.
- X -c Don't display and update a clock in echoline.
- X -d var=[val] Define/undefine variable var.
- X -d typ:[cmd] Set/unset type command for filetype typ.
- X -f lst Build tree from list file lst.
- X -g Don't use graphic characters.
- X -h Display usage and meaning of command line options.
- X -i ind Set maximal tree indention to ind
- X -l lev Build tree up to level lev.
- X -n Don't scan tree for changes in tree.
- X -o Omit saving changes in history/definitions/bindings.
- X -p lin Set file window to lin lines (1..9)
- X -q Build tree up to level 2 (like -l 2).
- X -r Recreate tree list (always scan disk).
- X -s Don't use hardware scrolling.
- X -t Sort files by modification times.
- X -u Update file lists in tree.
- X -v mod Set video attribute setting (0,1,2)
- X -w Suppress warnings about unreadable directories.
- X -x cmd Use string cmd as initial command input.
- X
- X The boolean options bcgnosw and the numerical options ipv may also
- X be pre-set in the environment variable UTREE.
- X#@
- X#@Global g: About global commands for tree and file screen
- X
- X The following commands are common for tree and file screen:
- X
- X C-z Terminate and leave utree.
- X C-c,C-y Cancel command or input.
- X C-l Refresh/redisplay screen.
- X Tab,C-t Move to next tagged directory or file.
- X h,?.C-r Change to help screen for displaying help pages.
- X @,C-@ Mark current directory or file.
- X #,C-g Move to previously marked directory/file or position.
- X a Display utree version.
- X d Display current date and time.
- X j Next directory or file (for vi fans).
- X k Previous directory or file (for vi fans).
- X w Display full pathname of current directory.
- X = Change to variables screen for setting variables.
- X : Change to commands screen for setting filetype commands.
- X | Change to bindings screen for binding keys.
- X ! Change to shell screen for execution of shell commands.
- X $ Escape to an interactive shell session.
- X#@
- X#@Tree t: About utree directory tree screen commands
- X
- X All tree commands can be given in lowercase or uppercase letters For
- X some commands a lowercase letter hits the current directory only, an
- X uppercase letter hits a complete subtree or all tagged files in subtree.
- X
- X >,CR,NL,SP Change to file screen of current directory.
- X < Change to file screen of parent directory.
- X C-n Move to next directory.
- X C-p Move to previous directory.
- X C-f Move to next directory on same level.
- X C-b Move to previous directory on same level.
- X C-v Move one page forward.
- X C-w Move one page backward.
- X C-a Move to begin of directory tree.
- X C-e Move to end of directory tree.
- X TAB,C-t Move to next directory containing tagged files.
- X C-u Scroll up directory tree.
- X C-d, Scroll down directory tree.
- X @,C-@ Mark current directory.
- X #,C-g Goto previously marked directory.
- X b,B Backup all files/tagged files in subtree.
- X c,C Change to a directory/Copy tagged files.
- X f,F Find files in current directory/subtree.
- X g,G Search for pattern in files in directory/subtree.
- X i Show some directory information.
- X l,L List files/tagged files in current subtree.
- X m,M Make a new directory/Move tagged files.
- X n,N Change sort criteria, sort files in directory/subtree.
- X o Write a list of directories, files or tagged files.
- X q Exit utree.
- X r,R Remove current directory/Remove tagged files.
- X s Show/change status of current directory.
- X t,T Tag files in current directory/subtree.
- X u,U Untag files in current directory/subtree.
- X z,Z Zoom files in current directory/subtree.
- X + Enlarge tree window if possible.
- X - Shrink tree window if possible.
- X / Scan tree and rebuild directories if needed.
- X \ Scan directory for subdirectories and insert subtree.
- X 0 Switch tree/user commands menuline.
- X 1..9 Execute user defined tree command.
- X
- X For further information about filename patterns for the commands find,
- X grep, list, tag, untag and zoom see the pattern help page.
- X#@
- X#@File f: About utree file screen commands
- X
- X All file commands can be given in lower or upper case letters.
- X For most commands a lowercase letter hits the current file only,
- X an uppercase letter hits all selected (tagged) files.
- X
- X q,CR,NL,SP Change back to tree screen.
- X C-f Move to next file.
- X C-b Move to previous file.
- X C-n Move to file on next line.
- X C-p Move to file on previous line.
- X C-v Move one page forward.
- X C-w Move one page backward.
- X C-a Move to first file.
- X C-e Move to last file.
- X TAB,C-t Move to next tagged file.
- X C-u Scroll up file screen.
- X C-d Scroll down file screen.
- X @,C-@ Mark current file.
- X #,C-g Goto previously marked file.
- X c,C Copy file/tagged files.
- X e,E Edit file/tagged files.
- X f Find files matching a pattern.
- X g,G Search for pattern in file/tagged files.
- X i,I Show some information about file/tagged files.
- X l,L List files matching a pattern/tagged files.
- X m,M Rename/move file/tagged files.
- X n Change sort criteria and resort file list.
- X p,P Send file/tagged files to printer spooler.
- X r,R Remove file/tagged files.
- X s,S Show/change status of file/tagged files.
- X t,T Tag/select files for further processing.
- X u,U Untag file/tagged files.
- X v,V View file/tagged files.
- X x Execute current file or call a command for it.
- X z Zoom files in file list.
- X > If current file is a directory, change to.
- X < Change back to parent directory.
- X / Rebuild file list (i.e. after shell escape).
- X 0 Switch file/user commands menuline.
- X 1..9 Execute user defined file command.
- X
- X For further information about filename patterns for the commands find,
- X grep, list, tag, untag and zoom see the pattern help page.
- X#@
- X#@Edit e: About utree line editor commands
- X
- X The builtin utree line editor knows the following functions:
- X (Function keys are supported if known by termcap/terminfo)
- X
- X CR,NL Accept and send input line.
- X C-c,C-y Cancel input line and line editor.
- X C-o Switch insert/overwrite mode.
- X C-l Redisplay input line.
- X C-f Move cursor one character forward.
- X C-b Move cursor one character backward.
- X C-a Move cursor to beginning of line.
- X C-b Move cursor to end of line.
- X C-v Scroll forward line.
- X C-w, Scroll backward line.
- X C-d Delete character under cursor.
- X C-h,DEL Delete character left from cursor.
- X C-x Delete line.
- X C-k Delete from cursor position to end of line.
- X C-t Transpose characters under and left from cursor.
- X C-r Display help menu and pages.
- X C-@ Set mark at current position.
- X C-g Move cursor to previously set mark.
- X C-p Get previous list entry into line editor.
- X C-n Get next list entry into line editor.
- X#@
- X#@Vars v: About utree variables
- X
- X Utree knows about and uses the following variables which may be
- X set/unset at startup in the startupfile '$HOME/.utree', with the
- X commandline option '-d' or the variables command '=':
- X
- X BL BELL Allow ringing of the bell.
- X CL CLOCK Show and update clock every second.
- X GC GRAPHCHARS Use graphical character set.
- X TS TERMSCROLL Use hardware terminal scrolling.
- X ST SCANTREE Allow scanning the filesystem for changes.
- X WD WARNDIRS Make warnings about unreadable directories.
- X LS LEXSORT Sort filenames in file lists in lexical order.
- X AS AUTOSAVE Save changes in history, variables and command
- X definitions and key bindings.
- X TI TREEINDENT Maximal tree indention on tree screen (3..9).
- X VM VIDEOMODE Using of video attributes (0=none,1,2=all).
- X FL FILELINES Maximal file lines on tree screen (1..9).
- X HS HISTSIZE Size of history list (Settable at startup only).
- X SH SHELL Interactive shell.
- X ED EDITOR Editor.
- X EO EDITOPTS Editor options.
- X PG PAGER File pager/viewer.
- X PO PAGEOPTS Pager options.
- X XD XDUMPER File hexdumper.
- X XO XDUMPOPTS Dumper options.
- X LP LPRINTER Printer spooler command.
- X LO LPRINTOPTS Printer options.
- X BK BACKUP Backup program.
- X BO BACKUPOPTS Backup options.
- X T1..9 TREECMD1..9 User defined commands 1..9 for tree screen.
- X F1..9 FILECMD1..9 User defined commands 1..9 for file screen.
- X
- X Variables are set with a line 'shorthand=value' or 'variable=value'
- X (i.e. 't1=ps -ef'), unset with a line 'shorthand=' or 'variable='
- X (i.e. 't1='). When defining user tree or file commands some sprintf
- X like format characters lead in by a percent sign ('%') have a
- X special meaning and are expanded before the command is executed (See
- X also the help page line). A sharp sign (#) in a variable definition
- X is used as leadin for a menu item of the defined user file or tree
- X command or as comment.
- X
- X E.g.: the variable definition 'fc1=wc -l %F # Count' for user
- X defined file command 1 is expanded to 'wc -l filename' and in the
- X user command file menu 'Count' is displayed behind menu item 1.
- X#@
- X#@Cmds c: About filetype dependent commands
- X
- X On file screen you can execute a file or a command on it with
- X the utree command execute ('x'). You are requested for parameters
- X if the current file is executable, for a command to execute on the
- X current file if the current file is not executable. For a type of file
- X you can define so called filetype commands which are called if the
- X current file matches this filetype (or extension).
- X
- X Filetype commands can be set/unset at startup in the startupfile
- X '$HOME/.utree', with the commandline option '-d' or the filetype
- X command ':' similar to setting/unsetting variables.
- X Filetype commands are set with a line like 'filetype:command'
- X (e.g. '*.c:cc -c -O'). The command ('cc -c -O') is then executed if
- X the current file matches the filetype pattern (e.g. '*.c' for 'foo.c').
- X Filetype commands are unset with a line 'filetype:' (i.e. '*.c:').
- X
- X When defining filetype commands some sprintf like format characters
- X lead in by a percent sign ('%') have a special meaning and are
- X expanded before the command is executed. For further information
- X about filename patterns and the format characters and her meaning
- X see the pattern and line help pages.
- X#@
- X#@Line l: About line format for tree, file and filetype commands
- X
- X When defining a user defined tree or file command or a filetype
- X command or when entering a shell command some sprintf like format
- X characters are known and expanded before the command is executed.
- X These format characters and their meaning are:
- X
- X %B,%b Basename of current file or directory.
- X %D,%d Full pathname of current directory.
- X %F,%f Filename of current file or directory.
- X %H,%h Full pathname of home directory.
- X %R,%r Full pathname of root directory.
- X %P,%p Full pathname of current file or directory.
- X %S,%s Additional parameter(s) for a command which are requested
- X before the command is executed.
- X
- X E.g. the command line 'command %s %f >%b.out' is expanded before
- X execution to 'command parameters filename basename.out' with filename
- X and basename.out ('%f', '%b.out') of the current file or directory and
- X parameters ('%s') which are requested before the command is executed.
- X
- X For further information about tree/file and filetype commands see
- X the vars and defs help pages.
- X#@
- X#@Keys k: About default and user definable key bindings
- X
- X The following list denotes the names of all utree keys, their default
- X key bindings and their meanings on tree and file screen or in the line
- X editor (See also the help pages global, tree, file and edit).
- X
- X SELECT (CR,NL) Select directory/file or accept input line.
- X FORWARD (C-f) Move forward directory/file or character.
- X BACKWARD (C-b) Move back directory/file or character.
- X NEXT (C-n) Move to next directory or file or get next list entry
- X into the line editor.
- X PREVIOUS (C-p) Move to previous directory or file or get previous list
- X entry into the line editor.
- X NEXTPAGE (C-v) Next page/Scroll forward input line.
- X PREVPAGE (C-w) Previous page/Scroll backward input line.
- X BEGIN (C-a) Move to beginning of directories/files or input line.
- X END (C-e) Move to end of directories/files or input line.
- X UP (C-u) Scroll down up one line directories or files.
- X DOWN (C-d) Scroll down one line directories or files (on screens)
- X or delete character under the cursor (in line editor).
- X INSERT (C-o) Toggle insert/overwrite mode flag (in line editor)
- X or change to current directory (on screens).
- X DELETE (BS) Delete character left from cursor (in editor) or
- X change to parent directory (on screens).
- X KILL (C-k) Delete from cursor position to end of input line.
- X SETMARK (C-@) Set a mark on current directory/file or at cursor
- X position.
- X GOTOMARK (C-g) Move to previously marked directory/file or character.
- X GOTOTAG (TAB) Move to tagged directory or file (on screens) or
- X transpose characters (in line editor).
- X HELP (C-r) Get help pages and change to help screen.
- X REFRESH (C-l) Refresh and redraw screen or input line.
- X CANCEL (C-x) Delete whole input line and leave line editor.
- X BREAK (C-c) Break current command or line editor.
- X EXIT (C-z) Terminate and leave utree.
- X
- X The following function keys are bound at startup if they are defined
- X in your system's termcap or terminfo database:
- X
- X CursorRight FORWARD
- X CursorLeft BACKWARD
- X CursorUp PREVIOUS
- X CursorDown NEXT
- X Home/Begin BEGIN
- X End END
- X NextPage NEXTPAGE
- X PreviousPage PREVPAGE
- X ScrollUp UP
- X ScrollDown DOWN
- X Insert INSERT
- X Delete DELETE
- X Clear REFRESH
- X Help HELP
- X Select SELECT
- X Do/Command SELECT
- X Mark SETMARK
- X Enter SELECT
- X
- X You may bind any key to the denoted utree key symbols or to string on
- X the binding screen or in terminal startup files with the name
- X '.utree-term' in your home directory ('term' is the terminal type from
- X $TERM). This files contain lines built like 'key_sequence=key_name'
- X or 'keysequence="string"' for string insertion bindings.
- X E.g. the line '\eh=HELP' binds the key <ESC><h> to HELP and and the
- X line '\ei="insert"' binds <ESC><i> to insertion of the string 'insert'
- X into the input buffer for further reading and interpretation.
- X#@
- X#@Patterns p: About pattern matching
- X
- X Some commands (list, find, grep, tag or untag) require filename
- X patterns for matching files using some special (meta) characters.
- X
- X File NAME pattern matching interprets the following meta chars:
- X * matches all characters in a filename.
- X ? matches one character in a filename.
- X [class] matches all characters enclosed in brackets '[' and ']'
- X where '!' and '-' have a special meaning, i.e.
- X [abc] matches the characters 'a', 'b' and 'c'.
- X [a-z_] matches the characters from 'a' to 'z' and '_'.
- X [!a-z_] matches all characters except 'a' to 'z' and '_'.
- X
- X File SIZE pattern matching interprets the following meta chars:
- X =size matches all files equate size
- X !size matches all files not equate size
- X >size matches all files larger than size
- X <size matches all files smaller than size
- X You may specify the file size in bytes (b, default), kilo bytes (k)
- X or mega bytes (m), i.e. '>2k' matches all files larger than 2 kb or
- X 2048 bytes.
- X
- X File TIME pattern matching interprets the following meta chars:
- X )time matches all files modified within time.
- X (time matches all files not modified within time.
- X You may specify time in minutes (m), hours (h, default), days (d) or
- X weeks (w), i.e. ')2d' matches all files modified within last 2 days.
- X
- X To combine file name, size and time patterns use
- X & for ANDing of name/size/time patterns
- X | for ORing of name/size/time patterns.
- X If a character is preceeded by a backslash (\) or enclosed in quotes
- X his interpretation is suppressed and he is used as he is.
- X#@
- X
- END_OF_FILE
- if test 22386 -ne `wc -c <'lib/utree.help'`; then
- echo shar: \"'lib/utree.help'\" unpacked with wrong size!
- fi
- # end of 'lib/utree.help'
- fi
- if test -f 'src/list.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/list.c'\"
- else
- echo shar: Extracting \"'src/list.c'\" \(22046 characters\)
- sed "s/^X//" >'src/list.c' <<'END_OF_FILE'
- X/*
- X * LIST.C
- X * UTREE directory and file list handling routines.
- X * 3.01-um klin, Tue Jun 4 14:17:17 1991
- X * klin, Tue Oct 15 14:02:37 1991, Handling of symlinks changed
- X * klin, Sat Oct 26 15:07:06 1991, Print tree list added
- X * writedlist() changed
- X * 3.02-um klin, Fri Nov 1 13:41:58 1991, Minor changes
- X * klin, Sun Nov 10 19:37:14 1991, buildlist() changed
- X * klin, Sun Nov 24 11:44:49 1991, Some error fixes reported by
- X * Rolf Gebhardt (RG 11/22/91)
- X * 3.03-um klin, Sat Feb 15 20:09:09 1992, Minor changes
- 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) Feb 15 1992 list.c";
- X#endif /* !lint */
- X
- X#include "defs.h"
- X
- X/* ---- External variables and functions ------------------------------ */
- X
- XEXTRN char *readdname();
- XEXTRN char *getversion();
- X
- X/* ---- Local/global functions and procedures --------------------------*/
- X
- X/*
- X * INTERNAL USED ROUTINES
- X */
- X
- X/* Compare filenames from flist. Called by qsort() */
- LOCAL int flistcmp(f1, f2)
- X register flist *f1, *f2;
- X{
- X if(sortbytime) {
- X if(FPTIM(f1) < FPTIM(f2))
- X return(99);
- X else if(FPTIM(f1) > FPTIM(f2))
- X return(-99);
- X }
- X return(CMP(FPFIL(f1), FPFIL(f2)));
- X
- X} /* flistcmp() */
- X
- X/* Compare filenames from directory name vector. Called by qsort() */
- LOCAL int dlistcmp(d1, d2)
- X register char **d1, **d2;
- X{
- X return(CMP(*d1, *d2));
- X
- X} /* dlistcmp() */
- X
- X/* Count directory level */
- LOCAL int countlevl(name)
- X register char *name;
- X{
- X register int n;
- X
- X if(*name == '/' && *(name+1) == '\0')
- X return(0);
- X n = 0;
- X while(*name)
- X if(*name++ == '/')
- X ++n;
- X return(n);
- X
- X} /* countlevl() */
- X
- X/* Align buffer size to avoid too often alloc and free */
- LOCAL unsigned alignbsiz(s, n)
- X register unsigned s;
- X register int n;
- X{
- X register unsigned ns;
- X
- X if(s == 0 || n == 0)
- X ns = 0;
- X else
- X for(ns = NBUFSZ; ns < s; ns += NBUFINC)
- X ;
- X return(ns);
- X
- X} /* alignbsiz() */
- X
- X/* Align filevector size to avoid too often alloc and free */
- LOCAL int alignnfils(n)
- X register int n;
- X{
- X register int nn;
- X
- X if(n == 0)
- X nn = 0;
- X else
- X for(nn = NFILES; nn < n; nn += NFILINC)
- X ;
- X return(nn);
- X
- X} /* alignnfils() */
- X
- X/*
- X * FILE LIST ROUTINES
- X */
- X
- X/* Update file f in file list */
- LOCAL VOID insertflist(dp, f)
- X register dlist *dp;
- X register int f;
- X{
- X struct stat st;
- X register char *pn;
- X
- X /* Get mode flag for file */
- X pn = pathname(FFNAM(dp, f), DPNAM(dp));
- X if((*statfun)(pn, &st) == 0) {
- X switch(STFMT(&st)) {
- X#ifdef S_IFLNK
- X case S_IFLNK: /* Symbolic link */
- X FMODE(dp, f) = FF_SLNK;
- X break;
- X#endif /* S_IFLNK */
- X#ifdef S_IFSOCK
- X case S_IFSOCK: /* Socket */
- X FMODE(dp, f) = FF_SOCK;
- X break;
- X#endif
- X case S_IFDIR: /* Directory */
- X FMODE(dp, f) = FF_DIR;
- X ++DNDIR(dp);
- X break;
- X default: /* Executable or other file */
- X FMODE(dp, f) = (st.st_mode & 0111) ? FF_EXEC : FF_NONE;
- X break;
- X }
- X FMTIM(dp, f) = st.st_mtime;
- X FSIZE(dp, f) = st.st_size;
- X }
- X else {
- X FMODE(dp, f) = FF_ERR;
- X FMTIM(dp, f) = (time_t) 0;
- X FSIZE(dp, f) = (off_t) 0;
- X }
- X FITAG(dp, f) = FF_NONE;
- X
- X} /* insertflist() */
- X
- X/* Delete an entry from file list */
- GLOBL VOID deleteflist(dp, f)
- X register dlist *dp;
- X register int f;
- X{
- X register int n;
- X
- X /* Do nothing and return if file list is not yet read in (RG 11/22/91) */
- X if(DFVEC(dp) == FNULL)
- X return;
- X /* Move up file name, tag and mode flag in file list */
- X n = f + 1;
- X if(FITAG(dp, f) && DNTAG(dp) > 0)
- X --DNTAG(dp);
- X while(n < DNFIL(dp)) {
- X FFNAM(dp, f) = FFNAM(dp, n);
- X FITAG(dp, f) = FITAG(dp, n);
- X FMODE(dp, f) = FMODE(dp, n);
- X ++f;
- X ++n;
- X }
- X /* Decrement counters */
- X --DNFIL(dp);
- X --filecount;
- X
- X} /* deleteflist() */
- X
- X/* Sort or resort file list from directory dp */
- GLOBL VOID sortflist(dp)
- X register dlist *dp;
- X{
- X register int f;
- X
- X f = sortbytime;
- X sortbytime = DSORT(dp) ? 1 : 0; /* Set flag for comparing */
- X if(DNFIL(dp) > 0) /* Sort/resort file list */
- X qsort((char *) DFVEC(dp), (unsigned) DNFIL(dp), sizeof(flist), flistcmp);
- X sortbytime = f;
- X
- X} /* sortflist() */
- X
- X/* Zoom file list of directory dp */
- GLOBL VOID zoomflist(dp)
- X register dlist *dp;
- X{
- X register int f, n;
- X
- X if(DZOOM(dp)) {
- X for(f = n = 0; f < DNFIL(dp); f++)
- X if(umatch(dp, f, DZOOM(dp))) {
- X if(n != f)
- X FLIST(dp, n) = FLIST(dp, f);
- X ++n;
- X }
- X DNFIL(dp) = n;
- X }
- X
- X} /* zoomflist() */
- X
- X/* Rebuild file list in some cases (i.e. cp, mv ..) */
- GLOBL int newflist(dp)
- X register dlist *dp;
- X{
- X char cfnam[NAMELEN];
- X struct stat st;
- X register flist *fv;
- X register char *fbp, *name, *fb;
- X register int i, j, k, nfil, ntag;
- X register unsigned size;
- X register DIR *dirfp;
- X
- X (void) putecho("Building %s", DPNAM(dp));
- X flushout();
- X /* Set/reset counter */
- X nfil = DNFIL(dp);
- X ntag = DNTAG(dp);
- X filecount -= DNFIL(dp);
- X DNFIL(dp) = DNDIR(dp) = DNTAG(dp) = 0;
- X
- X /* Get status of directory and read in */
- X if((*statfun)(DPNAM(dp), &st) == 0 && (dirfp = opendir(DPNAM(dp)))) {
- X /* Save name of current file */
- X if(nfil > 0) {
- X (void) strcpy(cfnam, FFNAM(dp, DFCUR(dp)));
- X /* Save flist array and file buffer */
- X if(ntag > 0) {
- X fb = DFBUF(dp);
- X fv = DFVEC(dp);
- X DFBUF(dp) = NULL;
- X DBSIZ(dp) = 0;
- X }
- X }
- X /* Count files */
- X for(i = 0; readdname(dirfp); i++)
- X ;
- X rewinddir(dirfp);
- X /* Align file count and buffer size */
- X i = alignnfils(i);
- X size = alignbsiz((unsigned) st.st_size, i);
- X /* Release current file list and file name buffer if needed */
- X if(DFBUF(dp) && DBSIZ(dp) < size) {
- X ufree(DFBUF(dp));
- X ufree((char *) DFVEC(dp));
- X DFBUF(dp) = NULL;
- X DBSIZ(dp) = 0;
- X }
- X /* Get memory for file list and file name buffer if not yet done */
- X if(DFBUF(dp) == NULL && i > 0) {
- X DFBUF(dp) = (char *) ualloc(size, sizeof(char)); /* RG 11/22/91 */
- X DFVEC(dp) = (flist *) ualloc((unsigned) i, sizeof(flist));
- X DBSIZ(dp) = size;
- X }
- X /* Fill up file list and file name buffer */
- X for(i = 0, fbp = DFBUF(dp); name = readdname(dirfp); i++) {
- X FFNAM(dp, i) = strcpy(fbp, name);
- X fbp += strlen(name) + 1;
- X insertflist(dp, i);
- X }
- X closedir(dirfp);
- X DNFIL(dp) = i;
- X sortflist(dp);
- X if(DZOOM(dp))
- X zoomflist(dp);
- X /* Set up other directory data */
- X DFLAG(dp) = FL_FIL;
- X DMTIM(dp) = st.st_mtime;
- X DCTIM(dp) = st.st_ctime;
- X DCANC(dp) = CANCD(DPNAM(dp));
- X /* Try to restore current file */
- X DFTOP(dp) = DFCUR(dp) = 0;
- X if(nfil > 0) {
- X for(i = 0; i < DNFIL(dp); i++)
- X if(cfnam[0] != *FFNAM(dp, i) || CMP(cfnam, FFNAM(dp, i)))
- X (void) gofile(dp, 1);
- X else
- X break;
- X if(i >= DNFIL(dp))
- X while(gofile(dp, -1))
- X ;
- X /* Try to restore tagged files */
- X if(ntag > 0) {
- X i = j = 0;
- X while(i < nfil) {
- X if(FVTAG(fv, i) == FF_TAG)
- X for(k = j; k < DNFIL(dp); k++)
- X if(*FVFIL(fv,i) == *FFNAM(dp,k) && EQU(FVFIL(fv,i), FFNAM(dp,k))) {
- X FITAG(dp, k) = FF_TAG;
- X ++DNTAG(dp);
- X j = k;
- X break;
- X }
- X ++i;
- X }
- X }
- X }
- X filecount += DNFIL(dp);
- X }
- X /* Error in stat: use defaults */
- X else {
- X ufree(DFBUF(dp));
- X ufree((char *) DFVEC(dp));
- X DFBUF(dp) = NULL;
- X DFVEC(dp) = FNULL;
- X DBSIZ(dp) = 0;
- X DFLAG(dp) = FL_FIL;
- X DMTIM(dp) = DCTIM(dp) = (time_t) -1;
- X DCANC(dp) = 0;
- X DFCUR(dp) = DFTOP(dp) = 0;
- X fileflag |= SF_TREE;
- X if(VARSET(V_WD)) {
- X puthelp("BUILD %s (Y:exit ELSE:continue)", DPNAM(dp));
- X if(errequest(CFNAM, "Cannot read directory. Exit ?") == 'y')
- X return(RV_END);
- X }
- X }
- X
- X /* Release saved flist array and file buffer */
- X if(ntag > 0) {
- X ufree(fb);
- X ufree((char *) fv);
- X }
- X
- X /* Set screen flags */
- X treeflag |= SF_ECHO;
- X fileflag |= SF_ECHO;
- X
- X return(RV_OK);
- X
- X} /* newflist() */
- X
- X/*
- X * DIRECTORY LIST ROUTINES
- X */
- X
- X/* Build and set tree info flag */
- GLOBL VOID infodlist()
- X{
- X register dlist *dp, *np;
- X register int i, j;
- X
- X /* For each dir in tree check if there are dirs on the same level */
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp)) {
- X DINFO(dp) = 0;
- X for(i = 1, j = DLEVL(dp) - 1; i < j; i++) {
- X for(np = (dlist *) DNEXT(dp); np && DLEVL(np) > (i + 1); np = (dlist *) DNEXT(np))
- X ;
- X if(np && DLEVL(np) == (i + 1))
- X DINFO(dp) |= 1 << (i - 1);
- X }
- X for(np = (dlist *) DNEXT(dp); np && DLEVL(np) > DLEVL(dp); np = (dlist *) DNEXT(np))
- X ;
- X if(np && DLEVL(np) == DLEVL(dp))
- X DINFO(dp) |= 1 << (i - 1);
- X }
- X
- X} /* infodlist() */
- X
- X/* Insert directory dname into directory tree list */
- LOCAL dlist *insertdlist(dname, nfils, fvec)
- X register char *dname;
- X register int nfils;
- X register flist *fvec;
- X{
- X register dlist *dp, *rp;
- X register char *np;
- X register int f;
- X
- X /* Get memory and save directory name */
- X dp = (dlist *) ualloc(1, sizeof(dlist));
- X np = strsav(pathname(dname, "/"));
- X
- X /* Set up pathname/filename and file list */
- X DPNAM(dp) = np;
- X DFNAM(dp) = basename(np);
- X DZOOM(dp) = NULL;
- X DNFIL(dp) = nfils;
- X DFVEC(dp) = fvec;
- X DNEXT(dp) = GNULL;
- X DFCUR(dp) = DFTOP(dp) = 0;
- X DNTAG(dp) = 0;
- X /* For each file in file list create an entry */
- X for(f = 0; f < nfils; f++)
- X insertflist(dp, f);
- X
- X /* Insert dlist into tree list */
- X if(droot == DNULL) {
- X DPREV(dp) = GNULL;
- X droot = dp;
- X }
- X else {
- X for(rp = droot; DNEXT(rp); rp = (dlist *) DNEXT(rp))
- X ;
- X DNEXT(rp) = (glist *) dp;
- X DPREV(dp) = (glist *) rp;
- X }
- X
- X /* Increment directory and file counters */
- X ++dircount;
- X filecount += nfils;
- X
- X return(dp);
- X
- X} /* insertdlist() */
- X
- X/* Rebuild directory list after creating a new directory */
- GLOBL dlist *newdlist(name, flag)
- X register char *name;
- X register int flag;
- X{
- X struct stat st;
- X register dlist *dp, *pdp, *ndp, *p;
- X register char *np;
- X register int levl;
- X
- X /* Allocate memory for new dlist entry and for pathname */
- X ndp = (dlist *) ualloc(1, sizeof(dlist));
- X np = strsav(pathname(name, CPNAM));
- X
- X /* Insert dlist into directory tree */
- X levl = CLEVL + 1;
- X for(pdp = cdlist, dp = (dlist *) CNEXT; dp && DLEVL(dp) >= levl; dp = (dlist *) DNEXT(dp)) {
- X if(DLEVL(dp) == levl && CMP(np, DPNAM(dp)) < 0)
- X break;
- X pdp = dp;
- X }
- X if(DNEXT(ndp) = DNEXT(pdp)) {
- X p = (dlist *) DNEXT(ndp);
- X DPREV(p) = (glist *) ndp;
- X }
- X DNEXT(pdp) = (glist *) ndp;
- X DPREV(ndp) = (glist *) pdp;
- X
- X /* Fill up dlist record data */
- X DPNAM(ndp) = np;
- X DFNAM(ndp) = basename(np);
- X DZOOM(ndp) = NULL;
- X if((*statfun)(np, &st)) { /* Bad stat: use defaults */
- X DMTIM(ndp) = DCTIM(ndp) = (time_t) -1;
- X DFLAG(ndp) = FL_FIL;
- X DCANC(ndp) = 0;
- X }
- X else {
- X DMTIM(ndp) = st.st_mtime;
- X DCTIM(ndp) = st.st_ctime;
- X DFLAG(ndp) = flag;
- X DCANC(ndp) = CANCD(np);
- X }
- X DSORT(ndp) = sortbytime ? 1 : 0;
- X DFBUF(ndp) = NULL;
- X DFVEC(ndp) = FNULL;
- X DBSIZ(ndp) = 0;
- X DLEVL(ndp) = levl;
- X if(DLEVL(ndp) > maxlevel)
- X maxlevel = DLEVL(ndp);
- X DNFIL(ndp) = DNDIR(ndp) = 0;
- X DDNUM(ndp) = DDNUM(pdp) + 1;
- X DFCUR(ndp) = DFTOP(ndp) = 0;
- X DNTAG(ndp) = 0;
- X
- X /* Increment all following dlist entry numbers */
- X for(dp = (dlist *) DNEXT(ndp); dp; dp = (dlist *) DNEXT(dp))
- X ++DDNUM(dp);
- X
- X /* Update counter, flags and return */
- X ++CNDIR;
- X ++dircount;
- X writeflag = 1;
- X checkindent();
- X infodlist();
- X return(ndp);
- X
- X} /* newdlist() */
- X
- X/* Delete current entry from directory list */
- GLOBL VOID deletedlist(rp)
- X register dlist *rp;
- X{
- X register dlist *dp, *p;
- X register int f;
- X
- X /* Search for parent directory of directory list entry dp */
- X for(dp = rp; dp && DLEVL(dp) >= DLEVL(rp); dp = (dlist *) DPREV(dp))
- X ;
- X
- X /* If found destroy file list entry in parent directory */
- X if(dp) {
- X if(DFVEC(dp)) { /* RG 11/22/91 */
- X for(f = 0; f < DNFIL(dp); f++)
- X if(EQU(FFNAM(dp, f), DFNAM(rp)))
- X break;
- X deleteflist(dp, f);
- X }
- X --DNDIR(dp);
- X }
- X
- X /* Close the directory tree list chain */
- X if(DNEXT(rp)) {
- X for(dp = (dlist *) DNEXT(rp); DNEXT(dp); dp = (dlist *) DNEXT(dp))
- X ;
- X while(dp != rp) {
- X p = (dlist *) DPREV(dp);
- X DDNUM(dp) = DDNUM(p);
- X dp = (dlist *) DPREV(dp);
- X }
- X p = (dlist *) DNEXT(rp);
- X DPREV(p) = DPREV(rp);
- X }
- X if(p = (dlist *) DPREV(rp))
- X DNEXT(p) = DNEXT(rp);
- X
- X /* Release memory */
- X ufree(DPNAM(rp));
- X ufree(DFBUF(rp));
- X ufree((char *) DFVEC(rp));
- X if(DZOOM(rp))
- X ufree(DZOOM(rp));
- X ufree((char *) rp);
- X
- X /* Decrement directory counter and update tree info flag */
- X --dircount;
- X infodlist();
- X
- X} /* deletedlist() */
- X
- X/* Write out directory list dependent on w to file name */
- GLOBL char *writedlist(name, rp, what, w)
- X register dlist *rp;
- X register char *name, *what;
- X register int w;
- X{
- X char list[NAMELEN];
- X register FILE *fp;
- X register dlist *dp, *p;
- X register unsigned long info;
- X register int f, i, levl;
- X time_t t;
- X
- X (void) strcpy(list, pathname(name, CPNAM));
- X if(fp = fopen(list, "w")) {
- X t = time((time_t *) 0);
- X if(w == 'm')
- X (void) fprintf(fp, "# %s: file list (matching %s)", getversion(), what);
- X else
- X (void) fprintf(fp, "# %s: %s list", getversion(), what);
- X (void) fprintf(fp, ", %s", ctime(&t));
- X dp = rp;
- X do {
- X if(w == 'd')
- X (void) fprintf(fp, "%s\n", DPNAM(dp));
- X else if(w == 'l') {
- X p = (dlist *) DNEXT(dp);
- X f = p && DLEVL(p) > DLEVL(rp);
- X if(dp == rp) {
- X (void) fprintf(fp, "R%s\n", DPNAM(rp));
- X (void) fprintf(fp, "%cH%s\n", f ? 'U' : 'H', DFNAM(rp));
- X }
- X else {
- X levl = DLEVL(rp) - 1;
- X info = DINFO(dp) >> levl;
- X (void) fprintf(fp, "%c", f ? 'V' : 'L');
- X for(i = 1; i < (DLEVL(dp) - levl - 1); i++)
- X (void) fprintf(fp, "I%c", info & (1 << (i-1)) ? 'V' : 'S');
- X (void) fprintf(fp, "I%cH%s\n", info & (1 << (i-1)) ? 'T' : 'L', DFNAM(dp));
- X }
- X }
- X else {
- X for(f = 0; f < DNFIL(dp); f++)
- X switch(w) {
- X case 'm':
- X if(umatch(dp, f, what))
- X goto WRITEFILE;
- X break;
- X case 't':
- X if( !ISTAG(dp, f))
- X break;
- X /*Fall thru*/
- X case 'f':
- WRITEFILE: (void) fprintf(fp, "%s\n", pathname(FFNAM(dp, f), DPNAM(dp)));
- X break;
- X }
- X }
- X dp = (dlist *) DNEXT(dp);
- X } while(dp && DLEVL(dp) > DLEVL(rp));
- X (void) fclose(fp);
- X return(list);
- X }
- X return(NULL);
- X
- X} /* writedlist() */
- X
- X/* Check directory list after file changes in directory name */
- GLOBL VOID checkdlist(name)
- X register char *name;
- X{
- X char fname[NAMELEN];
- X struct stat st;
- X register dlist *dp;
- X register char *sp;
- X
- X if( !ISDIR(name, st)) {
- X (void) strcpy(fname, name);
- X name = fname;
- X if(sp = strrchr(fname, '/'))
- X *sp = '\0';
- X if((*statfun)(name, &st)) /* Bad stat: do nothing */
- X return;
- X }
- X
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp)) {
- X if(EQU(DPNAM(dp), name) && CHKTIM(dp, st)) {
- X DFLAG(dp) = FL_CHG;
- X ++buildflag;
- X break;
- X }
- X }
- X
- X} /* checkdlist() */
- X
- X/* Scan directory tree for changes in filesystem */
- GLOBL int scandlist(rp)
- X register dlist *rp;
- X{
- X register dlist *dp;
- X
- X dp = rp;
- X do {
- X if(keypressed() && hitakey(NULL) < RV_NUL)
- X return(RV_INT);
- X if(DFLAG(dp) == FL_FIL && changedlist(dp)) {
- X DFLAG(dp) = FL_CHG;
- X ++buildflag;
- X }
- X } while((dp = (dlist *) DNEXT(dp)) && DLEVL(dp) > DLEVL(rp));
- X return(RV_OK);
- X
- X} /* scandlist() */
- X
- X/* Check if status of a directory has changed */
- GLOBL int changedlist(dp)
- X register dlist *dp;
- X{
- X struct stat st;
- X
- X return((*statfun)(DPNAM(dp), &st) == 0 && CHKTIM(dp, st));
- X
- X} /* changedlist() */
- X
- X/* Update directory list after changes in filesystem tree */
- GLOBL int updatedlist()
- X{
- X register dlist *dp;
- X register int c;
- X
- X c = RV_OK;
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp)) {
- X if(DFLAG(dp) == FL_CHG) {
- X if((c = newflist(dp)) != RV_OK)
- X break;
- X if(dp == cdlist)
- X fileflag |= SF_TREE;
- X }
- X }
- X buildflag = 0;
- X return(c);
- X
- X} /* updatedlist() */
- X
- X/*
- X * BUILD UP DIRECTORY TREE
- X */
- X
- X/* Build up directory tree and file lists recursively. Work is done hard. */
- X/* For each directory starting with directory pn up to level last a */
- X/* dlist entry is allocated, the dlist record is filled with all needed */
- X/* directory data, the directory file list and the file name buffer, and */
- X/* then inserted into the directory tree list. */
- GLOBL int buildread(pn, levl, last, intr)
- X register char *pn;
- X register int levl, last, intr;
- X{
- X char name[NAMELEN];
- X static int dnum = 0;
- X struct stat dst, fst;
- X register DIR *fp;
- X register dlist *dp;
- X register flist *fvec;
- X register char *fbuf, *fbufp, *fn;
- X register char **dvec;
- X register int nfils, ndirs, flag, i, rv;
- X register unsigned bsiz;
- X
- X /* Is pn a directory? */
- X if( !ISDIR(pn, dst))
- X return(RV_ERR);
- X
- X /* Check for keyboard interrupt if interrupt is allowed */
- X if(intr && keypressed() && hitakey(NULL) < RV_NUL)
- X return(RV_INT);
- X
- X /* Init variables */
- X ndirs = nfils = 0;
- X fvec = FNULL;
- X fbuf = NULL;
- X bsiz = 0;
- X flag = FL_NUL;
- X
- X /* Read in directory and build dlist entry */
- X if(levl < last && (fp = opendir(pn))) {
- X /* Count files */
- X for(i = 0; readdname(fp); i++)
- X ;
- X rewinddir(fp);
- X (void) putecho("Reading %s (%d files)", pn, i);
- X flushout();
- X /* Align nfils and bsiz to avoid too often alloc and free */
- X i = alignnfils(i);
- X bsiz = alignbsiz((unsigned) dst.st_size, i);
- X if(i > 0) {
- X /* Get memory for file buffer, file list and directory array */
- X fbuf = (char *) ualloc(bsiz, sizeof(char));
- X fvec = (flist *) ualloc((unsigned) i, sizeof(flist));
- X dvec = (char **) ualloc((unsigned) i, sizeof(char *));
- X }
- X else {
- X fbuf = NULL;
- X fvec = FNULL;
- X }
- X /* Read in directory, fill up file list and directory array */
- X for(nfils = 0, fbufp = fbuf; fn = readdname(fp); nfils++) {
- X FVFIL(fvec, nfils) = strcpy(fbufp, fn);
- X fbufp += strlen(fn) + 1;
- X (void) strcpy(name, pathname(fn, pn));
- X if((*statfun)(name, &fst)) {
- X FVTIM(fvec, nfils) = (time_t) 0;
- X FVSIZ(fvec, nfils) = (off_t) 0;
- X }
- X else {
- X FVTIM(fvec, nfils) = fst.st_mtime;
- X FVSIZ(fvec, nfils) = fst.st_size;
- X if(STFMT(&fst) == S_IFDIR && (hiddendirs || *fn != '.'))
- X dvec[ndirs++] = FVFIL(fvec, nfils);
- X }
- X }
- X closedir(fp);
- X /* Sort file list and directory array */
- X qsort((char *) fvec, (unsigned) nfils, sizeof(flist), flistcmp);
- X qsort((char *) dvec, (unsigned) ndirs, sizeof(char *), dlistcmp);
- X flag = FL_FIL;
- X }
- X
- X /* Insert dlist into tree list and set up dlist record */
- X dp = insertdlist(pn, nfils, fvec);
- X DFBUF(dp) = fbuf;
- X DFVEC(dp) = fvec;
- X DBSIZ(dp) = bsiz;
- X DCANC(dp) = CANCD(pn);
- X DMTIM(dp) = dst.st_mtime;
- X DCTIM(dp) = dst.st_ctime;
- X DFLAG(dp) = flag;
- X DSORT(dp) = sortbytime ? 1 : 0;
- X DLEVL(dp) = levl;
- X if(DLEVL(dp) > maxlevel)
- X maxlevel = DLEVL(dp);
- X DNDIR(dp) = ndirs;
- X DDNUM(dp) = dnum++;
- X
- X if(nfils > 0) {
- X /* Build a dlist entry for each directory found in directory list */
- X for(i = 0; i < ndirs; i++) {
- X (void) strcpy(name, pathname(dvec[i], pn));
- X ++levl;
- X rv = buildread(name, levl, last, intr);
- X --levl;
- X if(intr && rv == RV_INT)
- X break;
- X }
- X /* Release directory array */
- X ufree((char *) dvec);
- X }
- X
- X /* Set up tree info flag and return */
- X infodlist();
- X return(intr && rv == RV_INT ? RV_INT : RV_OK);
- X
- X} /* buildread() */
- X
- X/* Build up directory tree from tree list. File lists are built up later. */
- X/* For each directory starting with directory rn read in from tree list */
- X/* file lfn a dlist entry is allocated, the dlist record is filled with */
- X/* all needed directory data and inserted into the directory tree list. */
- X/* File list and file name buffer are initially unset and filled up later. */
- GLOBL int buildlist(rn, cwd, lfn)
- X register char *rn, *cwd, *lfn;
- X{
- X char name[NAMELEN];
- X struct stat st;
- X register FILE *fp;
- X register dlist *dp;
- X register char *pn;
- X register int dlen, dlev, dnum, i;
- X
- X /* Init variables */
- X dlen = strlen(rn);
- X dlev = countlevl(rn);
- X dnum = 0;
- X
- X /* Read in list file fn */
- X if(fp = fopen(lfn, "r")) {
- X (void) putecho("Building tree from list %s ... ", lfn);
- X flushout();
- X while(fgets(name, sizeof(name), fp)) {
- X if(VALID(name[0])) {
- X if(name[i = strlen(name) - 1] == '\n')
- X name[i] = '\0';
- X pn = pathname(name, cwd);
- X /* Skip bad entries in tree list */
- X if(strncmp(rn, pn, dlen) || stat(pn, &st) || STFMT(&st) != S_IFDIR) {
- X writeflag = 1;
- X continue;
- X }
- X /* Skip hidden directories if flag is not set */
- X if( !hiddendirs && *(basename(pn)) == '.')
- X continue;
- X /* Insert into tree list and file up record with directory */
- X /* data. File list and file name buffer are initially unset. */
- X dp = insertdlist(pn, 0, FNULL);
- X DFBUF(dp) = NULL;
- X DFVEC(dp) = FNULL;
- X DBSIZ(dp) = 0;
- X DCANC(dp) = CANCD(pn);
- X DMTIM(dp) = st.st_mtime;
- X DCTIM(dp) = st.st_ctime;
- X DFLAG(dp) = FL_NUL;
- X DSORT(dp) = sortbytime ? 1 : 0;
- X DLEVL(dp) = countlevl(pn) - dlev + 1;
- X if(DLEVL(dp) > maxlevel)
- X maxlevel = DLEVL(dp);
- X DNDIR(dp) = 0;
- X DDNUM(dp) = dnum++;
- X }
- X }
- X (void) fclose(fp);
- X }
- X
- X /* Set up tree info flag and return */
- X if(dnum) {
- X infodlist();
- X return(RV_OK);
- X }
- X return(RV_NUL);
- X
- X} /* buildlist() */
- X
- END_OF_FILE
- if test 22046 -ne `wc -c <'src/list.c'`; then
- echo shar: \"'src/list.c'\" unpacked with wrong size!
- fi
- # end of 'src/list.c'
- fi
- if test -f 'src/vars.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'src/vars.c'\"
- else
- echo shar: Extracting \"'src/vars.c'\" \(22215 characters\)
- sed "s/^X//" >'src/vars.c' <<'END_OF_FILE'
- X/*
- X * VARS.C
- X * UTREE variable handling routines.
- X * 3.01-um klin, Sun May 5 11:05:05 1991
- X * 3.02-um klin, Fri Nov 1 10:46:14 1991, Option -u changed to -n
- X * klin, Sun Nov 24 15:26:19 1991, Video attributes changed
- X * 3.03-um klin, Tue Feb 11 14:18:50 1992, Generic lists for variables
- X * and file type commands
- X * klin, Sat Feb 15 14:44:52 1992, Video handling and partinioning of
- X * directory and file windows changed
- X * klin, Sun Feb 23 18:45:19 1992, Keybindings and variable
- X * AUTOSAVE added
- X * klin, Fri Mar 6 09:34:43 1992, Release undefined commands
- X * a klin, Sun Mar 15 19:08:25 1992, Accept command without comment
- X * b klin, Thu Mar 19 10:23:54 1992, Don't free empty strings
- 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.03b-um (klin) Mar 19 1992 vars.c";
- X#endif /* !lint */
- X
- X#include "defs.h"
- X
- X/* ---- Local variables and definitions ------------------------------- */
- X
- X/* Format for user command menulines on tree and file screen */
- X#define UMENUFORM \
- X" 1: 2: 3: 4: 5: 6: 7: 8: 9: "
- X#define FIRST 3
- X#define OFFSET 8
- X#define TITLE 5
- X
- X#define XUNDEF ((xlist *) -1) /* Undefined or released xlist */
- X
- LOCAL int vcchg = 0; /* Variables/commands changed */
- LOCAL char *novar = ""; /* Empty string variable */
- X
- GLOBL VOID checkindent();
- GLOBL VOID checklines();
- LOCAL VOID setsortflag();
- X
- X/* ---- External variables and functions ------------------------------ */
- X
- XEXTRN char *getversion();
- XEXTRN char *strclean();
- X
- X/* ---- Functions and procedures -------------------------------------- */
- X
- X/*
- X * INTERNAL USED ROUTINES
- X */
- X
- X/* Show all variables */
- LOCAL int showallvars()
- X{
- X register vlist *vp;
- X register int l, c;
- X
- X l = firstline;
- X c = RV_OK;
- X clearwindow(firstline, lastline);
- X for(vp = VARTAB(0), l = firstline; vp; vp = (vlist *) VNEXT(vp)) {
- X (void) putfxy(0, l, 0, "%s %12s=", VSCUT(vp), VNAME(vp));
- X if(VTYPE(vp) == VT_B)
- X c = putfxy(16, l, 0, "%s", VVALE(vp) == VB_ON ? "ON" : "OFF");
- X else
- X c = putfxy(16, l, 0, "%s", VVALE(vp) ? VVALE(vp) : "");
- X if(VCOMM(vp))
- X (void) putfxy(c > columns/2 ? c : columns/2, l, 0, "#%s", VCOMM(vp));
- X if(++l > lastline && VNEXT(vp)) {
- X puthelp("VARIABLES (CR:continue Q:quit ELSE:set/unset)");
- X c = hitakey("More variables ?", echoline, DA_NONE);
- X if( !(c == ' ' || c == '\n'))
- X break;
- X clearwindow(firstline, lastline);
- X l = firstline;
- X }
- X }
- X treeflag = fileflag = SF_FULL;
- X return(c);
- X
- X} /* showallvars() */
- X
- X/* Display file type dependent commands */
- LOCAL int showallcmds()
- X{
- X register xlist *xp;
- X register int l, c;
- X
- X l = firstline;
- X c = RV_OK;
- X clearwindow(firstline, lastline);
- X for(xp = xroot, l = firstline; xp; xp = (xlist *) XNEXT(xp)) {
- X c = putfxy(0, l, 0, "%s:%s", XTYPE(xp), XCOMD(xp));
- X if(XCOMM(xp))
- X (void) putfxy(c > (columns/2) ? c+1 : columns/2, l, 0, "#%s", XCOMM(xp));
- X if(++l > lastline && XNEXT(xp)) {
- X puthelp("FILETYPE COMMANDS (CR:continue Q:quit ELSE:set/unset)");
- X c = hitakey("More filetype commands ?", echoline, DA_NONE);
- X if( !(c == ' ' || c == '\n'))
- X break;
- X clearwindow(firstline, lastline);
- X l = firstline;
- X }
- X }
- X treeflag = fileflag = SF_FULL;
- X return(c);
- X
- X} /* showallcmds() */
- X
- X/* Set sort criteria flag for file lists */
- LOCAL VOID setsortflag(f)
- X register int f;
- X{
- X register dlist *dp;
- X
- X sortbytime = f ? 0 : 1;
- X for(dp = droot; dp; dp = (dlist *) DNEXT(dp))
- X (void) sortlist(dp, sortbytime);
- X
- X} /* setsortflag() */
- X
- X/* Set tree indention variable */
- LOCAL int setindent(i)
- X register int i;
- X{
- X if(i < MININD || i > MAXIND) /* Out of range */
- X return(-1);
- X maxindent = indent = i; /* Set indention variables */
- X checkindent();
- X return(0);
- X
- X} /* setindent() */
- X
- X/* Set video mode variable */
- GLOBL int setvideomode(i)
- X register int i;
- X{
- X if(i < VMODE0 || i > VMODE2) /* Out of range */
- X return(-1);
- X else if(glitchcap && i > VMODE1) /* Respect glitches */
- X i = VMODE1;
- X videomode = i; /* Set video mode variables */
- X *VARVAL(V_VM) = videomode + '0';
- X return(0);
- X
- X} /* setvideomode() */
- X
- X/* Set number of file lines on tree screen */
- LOCAL int setfilelines(n)
- X register int n;
- X{
- X if(n < MINFIL || n > MAXFIL) /* Out of range */
- X return(-1);
- X maxnflines = n;
- X checklines(1);
- X return(0);
- X
- X} /* setfilelines() */
- X
- X/*
- X * USER COMMAND ROUTINES
- X */
- X
- X/* Build command line s from user command v with value p */
- GLOBL int userformat(s, p, v, w)
- X register char *s, *p, *w;
- X register int v;
- X{
- X char buf[INPLEN];
- X register char *fp, *pp;
- X register int c, n;
- X
- X pp = p;
- X n = 0;
- X while(*p) { /* Scan command format */
- X if(*p == '\\') {
- X *s++ = *++p;
- X if(*p)
- X ++p;
- X }
- X else if(*p == '%') {
- X switch(*++p) {
- X case 's': /* Request for parameter */
- X case 'S':
- X puthelp("%s: Parameter %d for %s", w, ++n, pp);
- X c = putecho("Give Parameter %d:", n);
- X if((c = getline(buf, sizeof(buf), c, 0, NULL, GNULL, 0)) < RV_NUL)
- X return(c);
- X fp = buf;
- X goto DOCOPY;
- X case 'B': /* Basename of directory or file */
- X case 'b':
- X if(v > V_FC0) {
- X if(CNFIL == 0)
- X return(RV_NUL);
- X (void) strcpy(buf, FFNAM(cdlist, CFCUR));
- X }
- X else
- X (void) strcpy(buf, CFNAM);
- X if(fp = strrchr(buf, '.'))
- X *fp = '\0';
- X fp = buf;
- X goto DOCOPY;
- X case 'F': /* Filename of directory or file */
- X case 'f':
- X if(v > V_FC0) {
- X if(CNFIL == 0)
- X return(RV_NUL);
- X fp = FFNAM(cdlist, CFCUR);
- X }
- X else
- X fp = CFNAM;
- X goto DOCOPY;
- X case 'R': /* Root directory */
- X case 'r':
- X fp = rootdir;
- X goto DOCOPY;
- X case 'H': /* Home directory */
- X case 'h':
- X fp = home;
- X goto DOCOPY;
- X case 'P': /* Full pathname of directory or file */
- X case 'p':
- X if(v > V_FC0) {
- X if(CNFIL == 0)
- X return(RV_NUL);
- X fp = CPNAM;
- X while(*fp)
- X *s++ = *fp++;
- X *s++ = '/';
- X fp = FFNAM(cdlist, CFCUR);
- X goto DOCOPY;
- X }
- X /* Directory: fall thru */
- X case 'D': /* Current directory name */
- X case 'd':
- X fp = CPNAM;
- DOCOPY: while(*fp)
- X *s++ = *fp++;
- X break;
- X case '%': /* As it is */
- X *s++ = '%';
- X break;
- X default:
- X return(RV_NUL); /* Bad format */
- X }
- X ++p;
- X }
- X else
- X *s++ = *p++;
- X }
- X
- X *s = '\0'; /* Terminate command line */
- X return(RV_OK);
- X
- X} /* userformat() */
- X
- X/* Execute an user defined command v */
- GLOBL int usercommand(v)
- X register int v;
- X{
- X char buf[EXECLEN];
- X register int c;
- X
- X /* Check if usercommand is set */
- X if( !VARSET(v))
- X return(errequest("User command", "Not defined"));
- X /* Build command line */
- X else {
- X c = userformat(buf, VARVAL(v), v, VARNAM(v));
- X if(c == RV_NUL)
- X return(errequest("User command", "Bad format"));
- X else if(c < 0)
- X return(c);
- X }
- X
- X puthelp("USER COMMAND: %s", buf);
- X c = callsystem(buf, 1, 0);
- X checkdlist(CPNAM);
- X
- X if(c != RV_OK)
- X return(errequest("User command", "Error in executing"));
- X return(hitakey("Return from user command (Hit a key)", lines-1, DA_REVERSE));
- X
- X} /* usercommand() */
- X
- X/*
- X * FILE TYPE COMMAND ROUTINES
- X */
- X
- X/* Set file type command */
- GLOBL xlist *setcommand(type, f)
- X register char *type;
- X register int f;
- X{
- X register xlist *xp, *pp, *p;
- X register char *comd, *comm;
- X
- X /* Search for filetype - command separator ':' */
- X if((comd = strchr(type, ':')) == NULL || comd == type)
- X return(XNULL);
- X else
- X *comd++ = '\0';
- X
- X /* Get additional comment lead in by '#' */
- X if(comm = strchr(comd, '#')) {
- X *comm++ = '\0';
- X comm = strclean(comm);
- X }
- X comd = strclean(comd);
- X
- X /* Search for file type to set in command list */
- X for(xp = xroot; xp; xp = (xlist *) XNEXT(xp))
- X if(EQU(type, XTYPE(xp)))
- X break;
- X
- X /* Replace or delete an existing file type command */
- X if(xp) {
- X ufree(XCOMD(xp));
- X ufree(XCOMM(xp));
- X if(comd == NULL || *comd == '\0') {
- X if(xroot && xp == xroot) {
- X if(xroot = (xlist *) XNEXT(xp))
- X XPREV(xroot) = GNULL;
- X else
- X xroot = XNULL;
- X }
- X else {
- X if(p = (xlist *) XPREV(xp))
- X XNEXT(p) = XNEXT(xp);
- X if(p = (xlist *) XNEXT(xp))
- X XPREV(p) = XPREV(xp);
- X }
- X ufree(XTYPE(xp));
- X ufree(xp);
- X xp = XUNDEF;
- X }
- X }
- X /* Ignore invalid definition */
- X else if(comd == NULL || *comd == '\0')
- X return(XUNDEF);
- X /* Create and insert a new entry in file type command list */
- X else if(xp = (xlist *) ualloc(1, sizeof(xlist))) {
- X XTYPE(xp) = strsav(type);
- X if(xroot && CMP(type, XTYPE(xroot)) < 0) {
- X for(pp = xroot; XNEXT(pp); pp = (xlist *) XNEXT(pp)) {
- X p = (xlist *) XNEXT(pp);
- X if(CMP(type, XTYPE(pp)) > 0)
- X break;
- X }
- X XPREV(xp) = (glist *) pp;
- X XNEXT(xp) = XNEXT(pp);
- X if(p = (xlist *) XNEXT(pp))
- X XPREV(p) = (glist *) xp;
- X XNEXT(pp) = (glist *) xp;
- X }
- X else {
- X if(xroot)
- X XPREV(xroot) = (glist *) xp;
- X XPREV(xp) = GNULL;
- X XNEXT(xp) = (glist *) xroot;
- X xroot = xp;
- X }
- X }
- X
- X /* Insert command and comment and return */
- X if(comd && *comd) {
- X XCOMD(xp) = strsav(comd);
- X XCOMM(xp) = comm && *comm ? strsav(comm) : NULL;
- X }
- X if(xp) {
- X if(f == VC_CHG)
- X vcchg = 1;
- X return(xp);
- X }
- X else
- X return(XNULL);
- X
- X} /* setcommand() */
- X
- X/* Show and set/unset filetype commands */
- GLOBL int commands()
- X{
- X char buf[3*INPLEN], typ[INPLEN], cmd[INPLEN], cmt[INPLEN];
- X register xlist *xp = XUNDEF;
- X register int c, f;
- X
- X who = "SET COMMAND";
- X f = 1;
- X /* Filetype command loop */
- X while(1) {
- X cmd[0] = cmt[0] = '\0';
- X if(f && ((c = showallcmds()) < RV_NUL || c == 'q'))
- X break;
- X f = 0;
- X if(xp == XUNDEF || xp == XNULL)
- X xp = xroot;
- X puthelp("%s: Give filetype or type:command (CR:quit)", who);
- X c = putecho("Set command:");
- X if((c = getline(typ, sizeof(typ), c, 'd', NULL, xp ? XLIST(xp) : GNULL, 1)) != RV_OK)
- X break;
- X if(strchr(typ, ':'))
- X (void) strcpy(buf, typ);
- X else {
- X puthelp("%s: Give command for %s (CR:unset)", who, typ);
- X c = putecho("Command for %s:", typ);
- X for(xp = xroot; xp; xp = (xlist *) XNEXT(xp))
- X if(EQU(typ, XTYPE(xp)))
- X break;
- X if((c = getline(cmd, sizeof(cmd), c, 'd', xp ? XCOMD(xp) : NULL, GNULL, 1)) < RV_NUL)
- X break;
- X if(c == RV_NUL)
- X (void) sprintf(buf, "%s:", typ);
- X else if(strchr(cmd, '#'))
- X (void) sprintf(buf, "%s:%s", typ, cmd);
- X else {
- X puthelp("%s: Give comment for %s", who, typ);
- X c = putecho("Comment for %s:", typ);
- X if((c = getline(cmt, sizeof(cmt), c, 'd', xp ? XCOMM(xp) : NULL, GNULL, 1)) < RV_NUL)
- X break;
- X else if(c == RV_OK)
- X (void) sprintf(buf, "%s:%s#%s", typ, cmd, cmt);
- X else
- X (void) sprintf(buf, "%s:%s", typ, cmd);
- X }
- X }
- X if((xp = setcommand(buf, VC_CHG)) == XNULL) {
- X puthelp("%s %s", who, hitkey);
- X if((c = errequest(buf, "Error in setting")) < RV_NUL)
- X break;
- X }
- X else
- X f = 1;
- X }
- X return(c);
- X
- X} /* commands() */
- X
- X/*
- X * VARIABLE ROUTINES
- X */
- X
- X/* Init variables */
- GLOBL VOID initvariables()
- X{
- X char buf[NAMELEN];
- X register vlist *vp;
- X register FILE *fp;
- X register char *ep;
- X register int i;
- X
- X /* Init user commands menu lines for tree and file screen */
- X (void) strcpy(utreemenu, UMENUFORM);
- X (void) strcpy(ufilemenu, utreemenu);
- X
- X /* First: Get and set variables from environment */
- X if(ep = getenv("SHELL"))
- X VARDEF(V_SH) = ep;
- X if(ep = getenv("EDITOR"))
- X VARDEF(V_ED) = ep;
- X if(ep = getenv("PAGER"))
- X VARDEF(V_PG) = ep;
- X
- X /* Second: Initialize and link variables table */
- X for(i = 0; VARNAM(i); i++) {
- X if(VARDEF(i) == NULL)
- X VARDEF(i) = novar;
- X VARVAL(i) = VARDEF(i);
- X }
- X VARNXT(0) = VARLST(1);
- X for(i = 1; VARNAM(i+1); i++) {
- X VARNXT(i) = VARLST(i+1);
- X VARPRV(i) = VARLST(i-1);
- X }
- X VARPRV(i) = VARLST(i-1);
- X
- X#ifdef UTSTART
- X /* Third: Get and set variables from startup file */
- X if(startup(buf, UTSTART) && (fp = fopen(buf, "r"))) {
- X while(fgets(buf, sizeof(buf), fp))
- X if(VALID(buf[0])) {
- X i = strlen(buf) - 1;
- X if(i > 0 && buf[i] == '\n')
- X buf[i] = '\0';
- X if(strchr(buf, '='))
- X (void) setvariable(buf, VC_SET);
- X else if(strchr(buf, ':'))
- X (void) setcommand(buf, VC_SET);
- X }
- X (void) fclose(fp);
- X }
- X#endif /* UTSTART */
- X
- X /* Last: Check environment variable UTREE */
- X if(ep = getenv("UTREE")) {
- X for(i = 0; ep[i]; i++)
- X switch(ep[i]) {
- X default: /* Do nothing */
- X break;
- X case 'b': /* No bell */
- X (void) setvariable("BL=", VC_SET);
- X break;
- X case 'c': /* No clock */
- X (void) setvariable("CL=", VC_SET);
- X break;
- X case 'g': /* No graphic chars */
- X (void) setvariable("GC=", VC_SET);
- X break;
- X case 'i': /* Tree indention */
- X if(isdigit(ep[i+1])) {
- X ++i;
- X (void) sprintf(buf, "TI=%c", ep[i]);
- X (void) setvariable(buf, VC_SET);
- X }
- X break;
- X case 'n': /* No tree scan for changes */
- X (void) setvariable("ST=", VC_SET);
- X break;
- X case 'o': /* Omit saving definition changes */
- X (void) setvariable("AS=", VC_SET);
- X break;
- X case 'p': /* File lines on tree screen */
- X if(isdigit(ep[i+1])) {
- X ++i;
- X (void) sprintf(buf, "FL=%c", ep[i]);
- X (void) setvariable(buf, VC_SET);
- X }
- X break;
- X case 's': /* No hardware scrolling */
- X (void) setvariable("TS=", VC_SET);
- X break;
- X case 'v': /* Set video mode */
- X if(isdigit(ep[i+1])) {
- X ++i;
- X (void) sprintf(buf, "VM=%c", ep[i]);
- X (void) setvariable(buf, VC_SET);
- X }
- X break;
- X case 'w': /* No warning about unreadable dirs */
- X (void) setvariable("WD=", VC_SET);
- X break;
- X }
- X }
- X
- X} /* initvariables() */
- X
- X/* Save current settings after changes */
- GLOBL VOID savevariables()
- X{
- X#ifdef UTSTART
- X char buf[NAMELEN];
- X register xlist *xp;
- X register vlist *vp;
- X register FILE *fp;
- X time_t t;
- X
- X if(VARVAL(V_AS) && vcchg) {
- X (void) sprintf(buf, ".%s", UTSTART);
- X (void) strcpy(buf, pathname(buf, home));
- X if(fp = fopen(buf, "w")) {
- X t = time((time_t *) 0);
- X (void) fprintf(fp, "# %s: ~/.%s, %s", getversion(), UTSTART, ctime(&t));
- X /* Save variables */
- X (void) fprintf(fp, "# Variables\n");
- X for(vp = VARTAB(0); vp; vp = (vlist *) VNEXT(vp)) {
- X (void) fprintf(fp, "%s=", VNAME(vp));
- X if(VVALE(vp))
- X (void) fprintf(fp, "%s", VTYPE(vp) == VT_B ? "ON" : VVALE(vp));
- X if(VCOMM(vp))
- X (void) fprintf(fp, "\t#%s\n", VCOMM(vp));
- X else
- X (void) fprintf(fp, "\n");
- X }
- X /* Save command settings */
- X (void) fprintf(fp, "# Commands\n");
- X for(xp = xroot; xp; xp = (xlist *) XNEXT(xp)) {
- X (void) fprintf(fp, "%s:%s", XTYPE(xp), XCOMD(xp) ? XCOMD(xp) : "");
- X if(XCOMM(xp))
- X (void) fprintf(fp, "\t#%s\n", XCOMM(xp));
- X else
- X (void) fprintf(fp, "\n");
- X }
- X (void) fclose(fp);
- X }
- X }
- X#endif /* UTSTART */
- X
- X} /* savevariables() */
- X
- X/* Check tree indention */
- GLOBL VOID checkindent()
- X{
- X register int i;
- X
- X if(maxlevel > 0) /* Calculate max possible indention */
- X i = (columns - FNAMSZ - 6) / maxlevel;
- X else
- X i = indent;
- X if(i < MININD) i = MININD;
- X if(i > MAXIND) i = MAXIND;
- X if(maxindent && i > maxindent) /* Check and set indention */
- X i = maxindent;
- X indent = i;
- X *VARVAL(V_TI) = indent + '0'; /* Set indention variable value */
- X treeflag = SF_TREE;
- X
- X} /* checkindent() */
- X
- X/* Calculate max possible number of file lines on tree screen */
- GLOBL int calculatelines()
- X{
- X register int l;
- X
- X if((l = (lines-3) / 2) > MAXFIL)
- X l = MAXFIL;
- X return(l);
- X
- X} /* calculatelines() */
- X
- X/* Check line partitioning on tree screen */
- GLOBL VOID checklines(f)
- X register int f;
- X{
- X register int m, nf;
- X
- X if(f) { /* Calculate new line values */
- X nf = nflines;
- X if(maxnflines < MINFIL)
- X nflines = MINFIL;
- X else {
- X m = calculatelines();
- X nflines = maxnflines > m ? m : maxnflines;
- X }
- X firstfline = lastfline - nflines + 1;
- X lastdline = firstfline - 2;
- X ndlines = lastdline - firstdline;
- X if(nf != nflines) /* Check directory window */
- X calculatetree(nf-nflines);
- X treeflag = SF_TREE;
- X }
- X else /* Update after resizing */
- X maxnflines = nflines;
- X *VARVAL(V_FL) = maxnflines + '0'; /* Set number of file lines */
- X
- X} /* checklines() */
- X
- X/* Set/unset or reset user defined variables */
- GLOBL int setvariable(line, f)
- X register char *line;
- X register int f;
- X{
- X register vlist *vp;
- X register char *value, *comm, *dp;
- X register int n, i, j;
- X
- X /* Search for variable - value separator '=' */
- X if(f != VC_TST) {
- X if(value = strchr(line, '='))
- X *value++ = '\0';
- X else
- X return(-1);
- X }
- X line = strclean(line);
- X strupper(line);
- X
- X /* Search for variable to set in variable list */
- X for(vp = VARTAB(0); vp; vp = (vlist *) VNEXT(vp))
- X if(*line == *VNAME(vp) && (EQU(line, VSCUT(vp)) || EQU(line, VNAME(vp))))
- X break;
- X if(vp == VNULL)
- X return(-1);
- X else if(f == VC_TST)
- X return(VNUMB(vp));
- X
- X /* Ignore additional comment */
- X if(comm = strchr(value, '#')) {
- X *comm++ = '\0';
- X comm = strclean(comm);
- X }
- X value = strclean(value);
- X
- X /* Set or unset variable */
- X n = VNUMB(vp);
- X switch(VTYPE(vp)) {
- X case VT_B: /* Booleans */
- X VVALE(vp) = *value ? VB_ON : VB_OFF;
- X if(n == V_GC)
- X initgraphics(VVALE(vp));
- X else if(n == V_LS)
- X setsortflag(VVALE(vp));
- X break;
- X case VT_N: /* Numbers */
- X if(n == V_TI && setindent(atoi(value)))
- X n = -1;
- X else if(n == V_VM && setvideomode(atoi(value)))
- X n = -1;
- X else if(n == V_FL && setfilelines(atoi(value)))
- X n = -1;
- X else if(n == V_HS && (f != VC_SET || sethistorysize(atoi(value))))
- X n = -1;
- X break;
- X case VT_S: /* General strings */
- X if(VVALE(vp) && VVALE(vp) != VDFLT(vp))
- X ufree(VVALE(vp));
- X if(*value && *value != '#' && (dp = strsav(value)))
- X VVALE(vp) = dp;
- X else if(VDFLT(vp))
- X VVALE(vp) = VDFLT(vp);
- X else
- X VVALE(vp) = NULL;
- X break;
- X case VT_U: /* Command strings */
- X if(VVALE(vp) && VVALE(vp) != VDFLT(vp))
- X ufree(VVALE(vp));
- X if(VCOMM(vp))
- X ufree(VCOMM(vp));
- X VVALE(vp) = VCOMM(vp) = NULL;
- X dp = NULL;
- X if(*value) {
- X if(dp = strsav(value))
- X VVALE(vp) = dp;
- X if(comm && *comm)
- X VCOMM(vp) = strsav(comm);
- X }
- X /* Update user command menulines if needed */
- X if(n > V_FC0)
- X for(i = (n - V_FC1) * OFFSET + FIRST, j = 0; j < TITLE; i++, j++)
- X ufilemenu[i] = comm && *comm ? *comm++ : ' ';
- X else
- X for(i = (n - V_TC1) * OFFSET + FIRST, j = 0; j < TITLE; i++, j++)
- X utreemenu[i] = comm && *comm ? *comm++ : ' ';
- X break;
- X case VT_O: /* User defined strings: not yet! */
- X default: /* ??? */
- X n = -1;
- X }
- X
- X if(n >= 0 && f == VC_CHG)
- X vcchg = 1;
- X return(n);
- X
- X} /* setvariable() */
- X
- X/* Show and set/unset common and user defined variables */
- GLOBL int variables()
- X{
- X char buf[3*INPLEN], var[INPLEN], def[INPLEN], cmt[INPLEN];
- X register char *dp;
- X register int f, c, n = -1;
- X
- X who = "SET VARIABLE";
- X /* Variable loop */
- X f = 1;
- X while(1) {
- X if(n < 0)
- X n = 0;
- X if(f && ((c = showallvars()) < RV_NUL || c == 'q'))
- X return(c);
- X f = 0;
- X puthelp("%s: Give variable or variable=value (CR:quit)", who);
- X c = putecho("Set variable:");
- X if((c = getline(var, sizeof(var), c, 'v', NULL, VARLST(n), 1)) != RV_OK)
- X break;
- X if(strchr(var, '='))
- X (void) strcpy(buf, var);
- X else {
- X if((n = setvariable(var, VC_TST)) < 0) {
- X if((c = errequest(var, "Unknown")) < RV_NUL)
- X break;
- X else
- X continue;
- X }
- X puthelp("%s: Give definition for %s (CR:unset)", who, var);
- X c = putecho("Set %s to:", var);
- X if(VARTYP(n) == VT_B)
- X dp = VARSET(n) ? "ON" : "";
- X else
- X dp = VARVAL(n);
- X if((c = getline(def, sizeof(def), c, 'v', dp, GNULL, 0)) < RV_NUL)
- X break;
- X if(VARTYP(n) != VT_U || strchr(def, '#'))
- X (void) sprintf(buf, "%s=%s", var, def);
- X else {
- X puthelp("%s: Give comment for user command %s", who, VARNAM(n));
- X c = putecho("Comment for %s:", VARNAM(n));
- X if((c = getline(cmt, sizeof(cmt), c, 'v', VARCOM(n), GNULL, 0)) < RV_NUL)
- X break;
- X (void) sprintf(buf, "%s=%s#%s", var, def, cmt);
- X }
- X }
- X if(setvariable(buf, VC_CHG) < 0) {
- X puthelp("%s %s", who, hitkey);
- X if((c = errequest(buf, "Error in setting")) < RV_NUL)
- X break;
- X }
- X else
- X f = 1;
- X }
- X
- X treeflag = fileflag = SF_FULL;
- X return(c);
- X
- X} /* variables() */
- X
- END_OF_FILE
- if test 22215 -ne `wc -c <'src/vars.c'`; then
- echo shar: \"'src/vars.c'\" unpacked with wrong size!
- fi
- # end of 'src/vars.c'
- fi
- echo shar: End of archive 5 \(of 8\).
- cp /dev/null ark5isdone
- 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
-