home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-07-19 | 50.7 KB | 1,818 lines |
- Newsgroups: comp.sources.x
- Path: uunet!darwin.sura.net!mips!msi!dcmartin
- From: Konstantinos Konstantinides <kk@hpkronos.hpl.hp.com>
- Subject: v18i031: xdtree (Motif), Part01/03
- Message-ID: <csx-18i031-xdtree@uunet.UU.NET>
- Originator: dcmartin@fascet
- Sender: dcmartin@msi.com (David C. Martin - Moderator)
- Organization: Molecular Simulations, Inc.
- Date: Mon, 20 Jul 1992 15:41:25 GMT
- Approved: dcmartin@msi.com
- Lines: 1805
-
- Submitted-by: Konstantinos Konstantinides <kk@hpkronos.hpl.hp.com>
- Posting-number: Volume 18, Issue 31
- Archive-name: xdtree/part01
-
- From the README:
-
- xdtree is an extension of dtree, the program originally written by
- Dave Borman. It is very similar to my old "dtree" I posted in
- comp.sources.x in 1990, but it has a new user interface, and I changed
- the name to xdtree to avoid any confusion with the original program.
- It displays on a terminal or under X11 (using Motif widgets) the tree
- structure of a Unix directory tree. On a color terminal, different
- colors can be used for files, directories, and symbolic links. On a
- monochrome terminal, one may try to use different button bitmaps for
- files and directories using the PushButton resources.
-
- #!/bin/sh
- # This is a shell archive (produced by shar 3.50)
- # To extract the files from this archive, save it to a file, remove
- # everything above the "!/bin/sh" line above, and type "sh file_name".
- #
- # made 07/20/1992 15:37 UTC by dcmartin@fascet
- # Source directory /home/fascet/dcmartin/csx/src/tmp
- #
- # existing files will NOT be overwritten unless -c is specified
- #
- # This is part 1 of a multipart archive
- # do not concatenate these parts, unpack them in order with /bin/sh
- #
- # This shar contains:
- # length mode name
- # ------ ---------- ------------------------------------------
- # 6123 -rw-r--r-- xdtree.1
- # 47318 -rw-r--r-- xdtree.c
- # 10452 -rw-r--r-- Makefile
- # 785 -rw-r--r-- XDtree
- # 2270 -rw-r--r-- xdtree-i.h
- # 261 -rw-r--r-- Imakefile
- # 1418 -rw-r--r-- README
- # 21424 -rw-r--r-- Tree.c
- # 2420 -rw-r--r-- Tree.h
- # 3293 -rw-r--r-- TreeP.h
- #
- if test -r _shar_seq_.tmp; then
- echo 'Must unpack archives in sequence!'
- echo Please unpack part `cat _shar_seq_.tmp` next
- exit 1
- fi
- # ============= xdtree.1 ==============
- if test -f 'xdtree.1' -a X"$1" != X"-c"; then
- echo 'x - skipping xdtree.1 (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xdtree.1 (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xdtree.1' &&
- .TH XDTREE 1L
- .SH NAME
- xdtree \- display directory tree structures
- .SH SYNOPSIS
- .B xdtree
- [
- .I \-aDfghHNpsStvx
- ] [
- .I \-l level
- ] [
- .I \-c linelength
- ] [
- .BR directory ...
- ]
- .SH DESCRIPTION
- .I xdtree
- is an extension of
- .I dtree
- and displays a graphic representation of the directory structure of each given
- .B directory
- and its children either on the terminal stdout or on an X11 window, using
- the Motif widgets (default). If no directories are specified, the current
- directory is used.
- By default, only directories, not regular files, are shown, and only their
- filenames are given. Various options add additional
- information to the tree.
- .SS OPTIONS
- .TP
- .I \-a
- Include files in the listing (excluding entries beginning with '.').
- .TP
- .I \-c linelength
- Make
- .I linelength
- the length of each
- column of the printout. By default, this is 14.
- Any entries longer than
- the column length are truncated accordingly, and the last character that
- fits into the column is replaced by an asterisk.
- This option only has an effect if the
- .I -v
- option is specified.
- .TP
- .I \-l level
- Search only up to the specified level. (Maximum is 10).
- .TP
- .I \-D
- List directories first. For each directory, its subdirectories
- will be listed first, and then all of its other entries.
- .TP
- .I \-f
- List files first. The reverse of
- .IR \-D .
- .TP
- .I \-S
- Long listing. Display useful information to the right of
- each entry: the name of the file's owner, its size in blocks, and its mode.
- .TP
- .I \-g
- Same as the
- .I \-S
- option, except that the group name is used instead of
- the owner name. If both the
- .I \-S
- and
- .I \-g
- options are used, both the
- owner and group will be displayed.
- .TP
- .I \-H
- Display a header at the top of the printout that gives the time and
- date that the printout was made and a summary of the type of
- information contained in the tree.
- .TP
- .I \-N
- No sort. Entries are listed in the order they are read
- from the directories.
- .TP
- .I \-p
- Include entries beginning with '.' (except '.' and '..').
- .TP
- .I \-s
- Simplify the long listing: display the user id, size in blocks, and
- octal mode of the file. This option implies the
- .I \-S
- option unless the
- .I \-g
- option is specified.
- .TP
- .I \-v
- Do not let column lengths vary; use the same
- width for each column of output. The width defaults to 14
- but can be set with the
- .I \-c
- option.
- .TP
- .I \-x
- Do not cross file systems.
- .I xdtree
- will not cross over to a
- subdirectory if it is on a different file system.
- .TP
- .I \-h
- Will print a list of the options.
- .TP
- .I \-t
- Terminal mode.
- In default mode
- .I
- xdtree
- will display the directory tree structure in an X11 window.
- The \-t option allows the tree to be printed on the terminal stdout.
- X
- Under the X11 window mode, a button click on a tree node, makes it
- the "active" node. The name of the "active" node always appears
- at the top of the window, under the "quit" button.
- Below the area where the name of the "active" node is shown,
- a table displays the mode of the node, the group and user IDs, and its
- size.
- Next to this menu are
- the \fIfile,\fR \fIdirectory,\fR and \fIPrint-Tree\fR option buttons.
- There are
- four \fIfile\fR options: \fIview, topview, edit\fR and \fIprint\fR.
- There are three \fIdirectory\fR options: \fIshow subtree, list files\fR,
- and \fIlist '../'\fR.
- Thus, the \-c, \-S, \-g, \-s, and \-v options are meaningful only
- when the \-t option is used.
- However, the \-S, \-g, and \-H options are accessible from the toggle buttons
- in the \fIPrint-Tree\fR options menu.
- .TP
- .B view
- Display the whole file on a scrolled window.
- Since the program reads a file all at once,
- the wait may be significant for a very large file. However, the option
- .TP
- .B topview
- shows only the top of the file (2000 bytes).
- .TP
- .B edit
- Edit the file. \fIxdtree\fR first checks and executes the command
- specified by the
- .B xdtree*editor:
- resource in .Xdefaults. If that command is NULL, \fIxdtree\fR
- forks an hpterm window using the editor command specified
- in the
- .B EDITOR
- environmental variable. If that variable is not specified, it uses \fIvi.\fR
- .TP
- .B print
- Print the file. It prints the file on the printer destination specified
- by the
- .B xdtree*lpdest:
- resource in .Xdefaults.
- If that variable is not specified it uses
- the default lp destination.
- The same variable is also being used when the \fIPrint-Tree\fR button
- is selected.
- .TP
- .B "show subtree"
- Show the directory subtree starting from the selected "active"
- directory node.
- .TP
- .B "list files"
- List all files and directories for the "active" directory node.
- This is equivalent to an "ls" command on that directory.
- .TP
- .B "list \.\.\/"
- List the directories in the parent (top) directory. Allows the user
- to traverse upwards the directory tree.
- .TP
- .B "Print-Tree"
- Print the tree. This is equivalent to using the \fIxdtree\fR command
- with the \-t option and piping the output to your printer.
- X
- Except for the \fIview\fR and \fItopview\fR options, in all other cases
- a click on the "quit" button of the "parent" will
- cause the "parent" \fIxdtree\fR window to freeze until the selected command
- has been executed or the "child" window has been killed.
- Then the "parent" window will automatically die.
- Thus it is recommended to kill "children" applications before
- you try to kill the "parent".
- X
- On a color terminal, one can choose different colors to distinguish
- between directories, files, and symbolic links.
- To set up a simple color scheme for \fIxdtree\fR, put the following entries
- in your ~/.Xdefaults file:
- X
- xdtree*geometry: 500x500
- .br
- xdtree*quit.background: DarkSlateBlue
- .br
- xdtree*dir.background: Red
- .br
- xdtree*sym_link.background: Brown
- .br
- xdtree*options.background: Red
- X
- A set of simple resources is also specified in
- /usr/lib/X11/app-defaults/XDtree
- .SH AUTHOR
- Dave Borman, Digital Unix Engineering Group, wrote the original
- dtree program.
- .br
- decvax!borman
- .br
- Originally written at St. Olaf College, Northfield, MN.
- .br
- Additions for the X11 windows display by K. Konstantinides,
- Hewlett-Packard Laboratories.
- Copyright: Hewlett-Packard, 1990, and 1992.
- e-mail:kk@hpkronos.hpl.hp.com
- SHAR_EOF
- chmod 0644 xdtree.1 ||
- echo 'restore of xdtree.1 failed'
- Wc_c="`wc -c < 'xdtree.1'`"
- test 6123 -eq "$Wc_c" ||
- echo 'xdtree.1: original size 6123, current size' "$Wc_c"
- rm -f _shar_wnt_.tmp
- fi
- # ============= xdtree.c ==============
- if test -f 'xdtree.c' -a X"$1" != X"-c"; then
- echo 'x - skipping xdtree.c (File already exists)'
- rm -f _shar_wnt_.tmp
- else
- > _shar_wnt_.tmp
- echo 'x - extracting xdtree.c (Text)'
- sed 's/^X//' << 'SHAR_EOF' > 'xdtree.c' &&
- /*
- X * DTREE - Print the tree structure of a directory
- X * 4/7/83 name was changed from TREE to DTREE
- X * 9/7/83 mods for 4.1c and 4.2 dirctory structure added
- X *
- X * Dave Borman, Digital Unix Engineering Group
- X * decvax!borman
- X * Originally written at St. Olaf College, Northfield MN.
- X * Copyright (c) 1983 by Dave Borman
- X * All rights reserved
- X * This program may not be sold, but may be distributed
- X * provided this header is included.
- X *
- X * Usage: xdtree [-aDfghHlNpstvx] [-c line-length] [directory...]
- X * Flags: -a) include non-directory entries in listing
- X * -D) sort tree with directories at the top
- X * -f) sort tree with files at the top
- X * -g) same as S, but use group name instead of user name
- X * -h) help
- X * -H) display a header at top
- X * -S) print stats with each listing
- X * if both g & S flags are given, both owner and
- X * group will be printed
- X * -N) do not sort the tree
- X * -p) include files starting with a '.' (except "." & "..")
- X * -s) use shorter stats. Implies -S if -g isn't given.
- X * -t) Use terminal mode (no X windows)
- X * -v) variable length columns off
- X * -x) do not cross mounted file systems.
- X * -c length) set max column length to "length"
- X * -l level) search up to the specified "level".
- X */
- X
- X /* Modified by Ed Arnold CSU-CS (csu-cs!arnold) 3-5-84
- X *
- X * Allows symbolic links to both directories and individual files.
- X * With a '-S' or '-aS' option, links are denoted with a 'l' in front of
- X * file or directory permissions. In all other instances both links to
- X * directories and files are represented just as files are. Contents of
- X * linked directories are not printed due to the possibility of
- X * recursively linked directories.
- X *
- X * Big directory name option added by:
- X * Mike Vevea CSU-CS (csu-cs!vevea) 3-22-84
- X *
- X * Toggle sense of -v (running 4.2), and eliminate some extraneous
- X * print info Mike Meyer Energy Analysts (mwm@ea) 4/17/84
- X *
- X * Fix the exit status to correctly indicate what happened.
- X * Mike Meyer Energy Analysts (mwm@ea) 4/23/84
- X *
- X * Change MAX to INITIAL_ELEM to fix conflict on Suns,
- X * fix incorrect default value for Clength when -v not given,
- X * add -H option to print header with date and description of tree,
- X * remove -b option (useless) and simplify array access,
- X * use getopt to parse options, fix usage message,
- X * use getwd instead of opening a pipe to pwd,
- X * make error messages more informative,
- X * use strncpy instead of sprintf for speed,
- X * move function declarations to top of file,
- X * comment out junk after #else and #endif,
- X * make symbolic link configuring automatic,
- X * check all error returns from malloc and realloc,
- X * add System V/Xenix/Unos compatibility,
- X * remove definition of rindex.
- X * David MacKenzie <djm@eng.umd.edu> 12/20/89
- X *
- X * Modified to display the tree on X11 windows using the Motif
- X * widgets and the Tree widget described by D.Young in his book,
- X * "The X Window System, Programming and applications with Xt,
- X * OSF/MOTIF EDITION", Prentice Hall, 1990.
- X * Clicking on the "active" node pops-up a menu with the Mode, and Group
- X * and User IDs. Clicking on "view" pops up a window with the whole
- X * contents of the file. Clicking on "topview" shows the top
- X * of the file only (2000 bytes).
- X * On the tree, files, directories, and symbolic links can be
- X * shown with different colors.
- X * Changed some options so there is no conflict with X-window
- X * options ( -d to -D, and -n to -N).
- X * Added the -t and -h options. Changed the -l option to -S
- X * Added the "-l level" option.
- X * Konstantinos Konstantinides, Hewlett-Packard Laboratories
- X * konstantinos_konstantinides@hplabs.hp.com 3/23/90
- X *
- X * Copyright: HEWLETT-PACKARD, 1990
- X * Motif is a trademark of Open Software Foundation, Inc.
- X * X Window System is a trademark of the Massachusetts Institute of
- X * Technology
- X *
- X * Added support for both the Tree and XmGraph widgets
- X * K. Konstantinides 4/16/90
- X *
- X * Rewrote the user interface, renamed program from dtree to xdtree
- X * K. Konstantinides 4/30/92
- X */
- X
- /* Compile-time options:
- X *
- X * STATS leave undefined to remove stats, giving more core space
- X * and thus the ability to tree larger tree structures on PDP 11/70s.
- X *
- X * NEWDIR directory structure a la Berkeley 4.1c or 4.2
- X *
- X * NDIR use <sys/ndir.h> instead of <sys/dir.h>
- X * NEWDIR must be defined as well.
- X *
- X * DIRENT use Posix directory library.
- X * NEWDIR must be defined as well.
- X *
- X * SYSV use getcwd instead of getwd, strrchr instead of rindex.
- X */
- void re_orient();
- void disarm_callback();
- void activate_callback();
- void arm_callback();
- void clickB();
- void w_print();
- void button_print();
- void pop_data();
- void view();
- void quit_b();
- void quit_b_pop();
- void do_menu(), stoggle(), htoggle(), gtoggle(), print_tree();
- X
- static char Sccsid[]="@(#)xdtree.c 2.0 4/30/92";
- X
- #ifdef S_IFLNK
- static char Rcsid[] ="$Header: xdtree.c,v 2.1 92/04/30 18:01:12 kk Exp $";
- #endif /* S_IFLNK */
- X
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <time.h>
- #include <string.h>
- #include <stdlib.h>
- X
- /* Include files for X windows */
- #include <X11/Intrinsic.h>
- #include <X11/Shell.h>
- #include <X11/StringDefs.h>
- #include <Xm/Xm.h>
- #include <Xm/Label.h>
- #include <Xm/PushB.h>
- #include <Xm/PushBG.h>
- #include <Xm/CascadeB.h>
- #include <Xm/RowColumn.h>
- #include <Xm/ScrolledW.h>
- #include <Xm/Separator.h>
- #include <Xm/MainW.h>
- #include <Xm/Frame.h>
- #include <Xm/Form.h>
- #include <Xm/Text.h>
- #include <Xm/ToggleB.h>
- #include "Tree.h"
- X
- /* Original Defs */
- #ifdef STATS
- # include <pwd.h>
- # include <grp.h>
- #endif /* STATS */
- X
- #ifdef NEWDIR
- # if DIRENT
- # include <dirent.h>
- # define direct dirent
- # else
- # if NDIR
- # include <sys/ndir.h>
- # else
- # include <sys/dir.h>
- # endif
- # endif /* DIRENT */
- #else
- # include <sys/dir.h>
- #endif /* NEWDIR */
- X
- /* default column length when -v is given */
- #ifdef unos
- #define DEFCOLWID 30
- #else
- #define DEFCOLWID 14
- #endif
- X
- #include <sys/param.h> /* for MAXPATHLEN */
- #ifndef MAXPATHLEN
- # ifdef LPNMAX /* Xenix from stdio.h */
- # define MAXPATHLEN (LPNMAX - 1)
- # else
- # include <limits.h> /* try somewhere else */
- # define MAXPATHLEN PATH_MAX
- # endif
- #endif
- X
- #ifndef MAXNAMLEN /* defined with NEWDIR routines */
- # ifdef LFNMAX /* Xenix again */
- # define MAXNAMLEN (LFNMAX - 1)
- # else
- # define MAXNAMLEN DEFCOLWID
- # endif
- #endif
- X
- #define DEPTH 10 /* maximum depth that dtree will go */
- #define INITIAL_ELEM 100 /* initial # of elements for list of files */
- X
- #define FFIRST 2 /* sort files first */
- #define DFIRST 1 /* sort directories first */
- #define FAIL -1 /* failure return status of sys calls */
- #define GREATER 1 /* return value of strcmp if arg1 > arg2 */
- #define LESSTHAN -1 /* return value of strcmp if arg1 < arg2 */
- #define SAME 0 /* return value of strcmp if arg1 == arg2 */
- X
- #ifdef STATS
- char *getmode();
- char *guid();
- char *ggid();
- struct passwd *getpwuid();
- struct group *getgrgid();
- #endif /* STATS */
- X
- #ifdef SYSV
- #define rindex strrchr
- #endif /* SYSV */
- X
- char *getwd();
- char *rindex();
- /*
- int qsort();
- char *malloc();
- char *realloc();
- */
- long time();
- X
- int compar(); /* comparison routine for qsort */
- char *xmalloc();
- char *xrealloc();
- X
- #ifdef SYSV
- #define getwd(buf) getcwd((buf), MAXPATHLEN + 1)
- #endif /* SYSV */
- X
- int Index = 0; /* current element of list[] */
- int CLength = 0; /* max length of a column */
- int All = 0; /* all != 0; list non-directory entries */
- int File_dir = 0; /* flag for how to sort */
- int Sort = 1; /* flag to cause sorting of entries */
- int Point = 1; /* skip point files if set */
- int Header = 0; /* print verbose header */
- int Maxes[DEPTH]; /* array keeps track of max length in columns */
- int Level = 0; /* counter for how deep we are */
- int Device; /* device that we are starting tree on */
- int Xdev = 1; /* set to allow crossing of devices */
- int Varspaces = 1; /* set to allow compaction of column width */
- #ifdef STATS
- int Gflag = 0; /* set for group stats instead of owner */
- int Longflg = 0; /* set for long listing */
- int Compact = 0; /* set for shortened long listing */
- #endif /* STATS */
- #undef Status
- struct stat Status;
- #ifdef S_IFLNK
- struct stat Lstat; /* stat of link, if there is one */
- #endif /* S_IFLNK */
- X
- struct entry {
- X int next; /* index to next element in list */
- X /* could be a ptr, but realloc() */
- X /* might screw us then */
- #ifdef STATS
- X off_t e_size; /* size in blocks */
- X unsigned short e_mode; /* file mode */
- X short e_uid; /* uid of owner */
- X short e_gid; /* gid of owner */
- #endif /* STATS */
- X unsigned short dir : 1; /* entry is a directory */
- X unsigned short last : 1; /* last entry in the dir. */
- X unsigned short dev : 1; /* set if same device as top */
- X unsigned short end : 13; /* index of last subdir entry*/
- X char e_name[MAXNAMLEN + 1]; /* name from directory entry */
- X char path_name[MAXPATHLEN + 1]; /* path name */
- } *List, *SaveList;
- X
- unsigned Size; /* how big of space we've malloced */
- X
- char *Spaces; /* used for output */
- char Buf1[BUFSIZ]; /* buffers for stdio stuff. We don't want */
- #ifndef NEWDIR
- char Buf2[BUFSIZ]; /* anyone calling malloc, because then */
- X /* realloc() will have to move the whole list */
- #endif
- #define FS(str) (void) fprintf(stderr,str)
- X
- help()
- {
- X fprintf(stderr,
- #ifdef STATS
- X "Usage: xdtree [-aDfghHlNpstvx] [-c linelength] [directory ... ]\n"
- #else /* STATS */
- X "Usage: xdtree [-aDfhHNptvx] [-c linelength] [directory ... ]\n"
- #endif /* STATS */
- X );
- FS(" options -a) include non-directory entries in listing\n");
- FS(" -D) sort tree with directories at the top\n");
- FS(" -f) sort tree with files at the top\n");
- FS(" -h) help - prints this message\n");
- FS(" -H) display a header at top\n");
- FS(" -x) do not cross mounted file systems.\n");
- FS(" -p) include files starting with a . (except . and ..)\n");
- FS(" -N) do not sort the tree\n");
- FS(" -t) Use terminal mode, don't display on an X window\n\n");
- FS(" -l level) Search only up to the specified level \n\n");
- FS(" Valid only if -t is used. Under default mode, a click on a \n");
- FS(" node pops up a menu with mode, user and group ids.\n\n");
- FS(" -S) print stats with each listing\n");
- FS(" if both g & S flags are given, both owner and\n");
- FS(" group will be printed\n");
- FS(" -g) same as S, but use group name instead of user name \n");
- FS(" -s) use shorter stats. Implies -S if -g isn't given.\n");
- FS(" -v) variable length columns \n");
- FS(" -c length) set max column length to -length-\n");
- FS(" X-Window version 2.0 4/30/92 \n");
- }
- int newlevel = DEPTH;
- Widget boxes[12], options;
- Widget submenu_file, submenu_dir,file_menu, dir_menu;
- struct entry *file_pointer;
- int S_flag = FALSE;
- int H_flag=FALSE;
- int g_flag=FALSE;
- X
- X
- main(argc, argv)
- char **argv;
- int argc;
- {
- X extern int optind;
- X extern char *optarg;
- X register int i;
- X char top[MAXPATHLEN + 1]; /* array for treetop name */
- X char home[MAXPATHLEN + 1]; /* starting dir for multiple trees */
- X char *ptr;
- X
- X Widget toplevel;
- X Widget sw, tree, q_button, w_button;
- X Widget menu_bar, frame, main_w, title;
- X Arg wargs[10],arg[15];
- X int flagX=1; /* use X windows as default */
- X Widget quit_menu, exit_b, reorient;
- X int really_quit, n;
- X
- X setbuf(stdout, Buf1);
- X
- X while ((i = getopt (argc, argv,
- #ifdef STATS
- X "haDfgHl:NpsSvxtc:"
- #else
- X "haDfHl:Npvxtc:"
- #endif /* STATS */
- X )) != EOF) {
- X switch (i) {
- X case 'a':
- X All = 1;
- X break;
- X case 'c':
- X CLength = atoi(optarg);
- X if (CLength > MAXNAMLEN)
- X CLength = MAXNAMLEN;
- X else if (CLength < 1)
- X CLength = DEFCOLWID;
- X break;
- X case 'l':
- X newlevel = atoi(optarg);
- X if(newlevel > DEPTH) {
- X newlevel = DEPTH;
- X fprintf(stderr,"Warning: Depth is limited by DEPTH=%d\n",newlevel);
- X }
- X break;
- X case 'D':
- X File_dir = DFIRST;
- X break;
- X case 'f':
- X File_dir = FFIRST;
- X break;
- X case 'H':
- X Header = 1;
- X break;
- X case 'N':
- X Sort = 0;
- X break;
- X case 'p':
- X Point = 0;
- X break;
- X case 'v':
- X Varspaces = 0;
- X break;
- X case 'x':
- X Xdev = 0;
- X break;
- X case 't':
- X flagX = 0;
- X break;
- X
- X case 'h':
- X help();
- X exit(0);
- #ifdef STATS
- X case 'g':
- X Gflag = 1;
- X break;
- X case 'S':
- X Longflg = 1;
- X break;
- X case 's':
- X Compact = 1;
- X break;
- #endif /* STATS */
- X default:
- X help();
- X exit(FAIL);
- X }
- X }
- #ifdef STATS
- X if (Compact && !Gflag)
- X Longflg = 1;
- #endif /* STATS */
- X if (CLength == 0)
- X CLength = Varspaces ? MAXNAMLEN : DEFCOLWID;
- X
- X /* Establish where we are (our home base...) */
- X if (getwd(home) == 0) {
- X fprintf(stderr,
- X "xdtree: Cannot get initial directory: %s\n", home);
- X exit(1);
- X }
- X
- X Spaces = xmalloc(MAXNAMLEN+2);
- X for(i = 0; i <= MAXNAMLEN; i++)
- X Spaces[i] = ' ';
- X Spaces[i] = '\0';
- X
- X /* Get initial Storage space */
- X Size = sizeof(struct entry) * INITIAL_ELEM;
- X SaveList = (struct entry *)xmalloc(Size);
- X
- X /* adjust for no specified directory */
- X if (optind == argc )
- X if(optind > 1) argv[--optind] = ".";
- X else { argv[1] = ".", optind = 1; argc = 2;}
- X
- X if (Header)
- X print_date();
- X
- X /* walk down the rest of the args, treeing them one at at time */
- X for (; optind < argc; optind++) {
- X if (chdir(home) == -1) {
- X fprintf(stderr, "xdtree: Cannot change to initial directory ");
- X perror(home);
- X exit(1);
- X }
- X strncpy (top, argv[optind], MAXPATHLEN);
- X
- X if (chdir(top) == FAIL) {
- X fprintf(stderr, "xdtree: Cannot change to top directory ");
- X perror(top);
- X continue;
- X } else if (getwd(top) == 0) {
- X fprintf(stderr,"xdtree: Cannot get current directory: %s\n", top);
- X continue;
- X }
- X
- X List = SaveList; Index = 0;
- X getwd(List[0].path_name);
- X ptr = rindex(top, '/');
- X
- X if (!ptr || *++ptr == '\0')
- X strncpy(List[Index].e_name, top, MAXNAMLEN);
- X else
- X strncpy(List[Index].e_name, ptr, MAXNAMLEN);
- X
- X if(stat(top, &Status) == FAIL) {
- X fprintf(stderr, "xdtree: Cannot stat directory ");
- X perror(top);
- X continue;
- X }
- X Device = Status.st_dev;
- X List[0].dir = 1;
- X List[0].last = 1;
- X List[0].next = 1;
- #ifdef STATS
- X List[0].e_mode = Status.st_mode;
- X List[0].e_uid = Status.st_uid;
- X List[0].e_gid = Status.st_gid;
- X List[0].e_size = Status.st_size;
- #endif /* STATS */
- X Index = 1;
- X for (i = 1; i < DEPTH; i++)
- X Maxes[i] = 0;
- X Maxes[0] = stln(List[0].e_name);
- X Level = 1;
- X
- X /* Don't waste time if there is no display */
- X if(flagX == 1)
- X toplevel = XtInitialize(argv[0], "XDtree", NULL, 0, &argc, argv);
- X
- X fprintf(stderr,"Started searching....Please wait \n");
- X /* search the tree */
- X List[0].end = t_search(top, &List[0]);
- X
- X if (Index == 1) /* empty tree */
- X List[0].next = 0;
- X
- X if (Header) {
- X if (All)
- X printf("\nDirectory structure and contents of %s\n", top);
- X else
- X printf("\nDirectory structure of %s\n", top);
- X if (Point)
- X printf("(excluding entries that begin with '.')\n");
- X }
- X
- X if(flagX == 0) pt_tree();
- X else {
- X
- X /* Create a Form, with button options and a Frame window
- X Put on the Frame, a ScrolledWindow and the Tree window
- X The Top has a quit button and the directory Name
- X */
- X fprintf(stderr,"Opening display now...Please wait\n");
- X
- X /* main window */
- X n=0;
- X main_w = XtCreateManagedWidget(NULL, xmFormWidgetClass,
- X toplevel, wargs, n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
- X menu_bar = XmCreateMenuBar(main_w,"menu",arg,n);
- X XtManageChild(menu_bar);
- X
- X
- X /* quit button */
- X
- X quit_menu = XmCreatePulldownMenu(menu_bar,
- X "quit_menu",NULL,0);
- X XtSetArg(wargs[0], XmNsubMenuId,quit_menu);
- X q_button = XmCreateCascadeButton(menu_bar,
- X "quit",wargs,1);
- X XtManageChild(q_button);
- X
- X w_button =XtCreateManagedWidget("warning",
- X xmLabelWidgetClass,quit_menu, NULL,0);
- X w_print(w_button,"Don't exit unless all children are dead\n");
- X exit_b = XtCreateManagedWidget("Exit",
- X xmPushButtonWidgetClass, quit_menu, NULL, 0);
- X XtAddCallback(exit_b, XmNarmCallback,
- X arm_callback, &really_quit);
- X XtAddCallback(exit_b, XmNdisarmCallback,
- X disarm_callback, &really_quit);
- X XtAddCallback(exit_b, XmNactivateCallback,
- X activate_callback, &really_quit);
- X
- X /* Create the options buttons */
- X file_pointer = &List[0];
- X show_menu(main_w,file_pointer,menu_bar);
- X
- X title = XtCreateManagedWidget("title",
- X xmCascadeButtonWidgetClass, menu_bar, NULL,0);
- X XtSetArg(wargs[0],XmNmenuHelpWidget, title);
- X XtSetValues(menu_bar, wargs, 1);
- X w_print(title,top);
- X
- X /* frame */
- X n=0;
- X XtSetArg(arg[n], XmNshadowType, XmSHADOW_OUT); n++;
- X XtSetArg(arg[n], XmNtopWidget, submenu_file); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- X frame = XmCreateFrame(main_w,"frame",arg,n);
- X XtManageChild(frame);
- X
- X XtSetArg(wargs[0], XmNscrollingPolicy, XmAUTOMATIC);
- X sw = XtCreateManagedWidget("swindow",
- X xmScrolledWindowWidgetClass, frame, wargs, 1);
- X
- X
- X /* Tree widget */
- X tree = XtCreateManagedWidget("tree",XstreeWidgetClass,
- X sw, NULL,0);
- X show_dtree(tree);
- X clickB(options,file_pointer,NULL);
- X XtRealizeWidget(toplevel);
- X XtMainLoop();
- X }
- X
- X }
- X exit(0) ;
- }
- X
- X
- t_search(dir, addrs)
- char *dir;
- struct entry *addrs;
- {
- X int bsort; /* index to begin sort */
- X int stmp; /* save temporary index value */
- X struct entry *sstep; /* saved step in list */
- X int nitems; /* # of items in this directory */
- #ifdef NEWDIR
- X DIR *dirp; /* pointer to directory */
- #else
- X FILE *dirp;
- #endif
- X char sub[MAXNAMLEN+1]; /* used for subdirectory names */
- X int i;
- #ifdef NEWDIR
- X struct direct *dp;
- #else
- X struct direct dirent;
- X struct direct *dp = &dirent;
- #endif /* NEWDIR */
- X int n_subs = 0;
- X int tmp = 0;
- X
- #ifdef NEWDIR
- X dirp = opendir(".");
- #else
- X dirp = fopen(".", "r");
- #endif /* NEWDIR */
- X if (dirp == NULL) {
- X fprintf(stderr, "xdtree: Cannot open directory ");
- X perror(dir);
- X return(0);
- X }
- #ifndef NEWDIR
- X setbuf(dirp, Buf2);
- #endif /* NEWDIR */
- X
- X bsort = Index;
- X sstep = &List[bsort]; /* initialize sstep for for loop later on */
- X nitems = Index;
- X /* get the entries of the directory that we are interested in */
- #ifndef NEWDIR
- X while (fread((char *)(dp), sizeof(struct direct), 1, dirp) == 1) {
- #else
- X while ((dp = readdir(dirp)) != NULL) {
- #endif /* NEWDIR */
- X
- X if (dp->d_ino
- #ifdef unos
- X == -1
- #else
- X == 0
- #endif /* unos */
- X || (strcmp(dp->d_name, ".") == SAME)
- X || (strcmp(dp->d_name, "..") == SAME)
- X || (Point && dp->d_name[0] == '.'))
- X continue;
- X
- X strncpy(sub, dp->d_name, MAXNAMLEN);
- #ifdef S_IFLNK
- X if (lstat(sub,&Lstat) == FAIL) {
- X fprintf(stderr, "xdtree: In directory %s, cannot lstat entry ", dir);
- X perror(sub);
- X continue;
- X }
- #endif /* S_IFLNK */
- X if (stat(sub, &Status) == FAIL) {
- X fprintf(stderr, "xdtree: In directory %s, cannot stat entry ", dir);
- X perror(sub);
- X continue;
- X }
- #ifdef S_IFLNK
- X if (((Lstat.st_mode & S_IFMT) == S_IFLNK) &&
- X ((Status.st_mode & S_IFMT) == S_IFDIR))
- X List[Index].dir = 0;
- X else if ((((Lstat.st_mode & S_IFMT) == S_IFLNK) &&
- X ((Status.st_mode & S_IFMT) != S_IFDIR)) && (All))
- X List[Index].dir = 0;
- #endif /* S_IFLNK */
- X else if ((Status.st_mode & S_IFMT) == S_IFDIR)
- X List[Index].dir = 1;
- X else if (All)
- X List[Index].dir = 0;
- X else
- X continue;
- X strncpy(List[Index].e_name, dp->d_name, MAXNAMLEN);
- X getwd(List[Index].path_name);
- X List[Index].last = 0;
- X List[Index].end = 0;
- #ifdef S_IFLNK
- X if ((Lstat.st_mode & S_IFMT) == S_IFLNK) {
- X List[Index].dev = (Device == Lstat.st_dev);
- X List[Index].e_mode = Lstat.st_mode;
- X List[Index].e_uid = Lstat.st_uid;
- X List[Index].e_gid = Lstat.st_gid;
- X List[Index].e_size = Lstat.st_size;
- X }
- X else {
- #endif /* S_IFLNK */
- X List[Index].dev = (Device == Status.st_dev);
- #ifdef STATS
- X List[Index].e_mode = Status.st_mode;
- X List[Index].e_uid = Status.st_uid;
- X List[Index].e_gid = Status.st_gid;
- X List[Index].e_size = Status.st_size;
- #endif /* STATS */
- #ifdef S_IFLNK
- X }
- #endif /* S_IFLNK */
- X if (stln(List[Index].e_name) > Maxes[Level])
- X Maxes[Level] = stln(List[Index].e_name);
- X ++Index;
- X if (Index*sizeof(struct entry) >= Size) {
- X Size += 20*sizeof(struct entry);
- X List = (struct entry *)xrealloc((char *)List, Size);
- X }
- X }
- #ifdef NEWDIR
- X closedir(dirp);
- #else
- X fclose(dirp);
- #endif /* NEWDIR */
- X
- X nitems = Index - nitems; /* nitems now contains the # of */
- X /* items in this dir, rather than */
- X /* # total items before this dir */
- X
- X if (Sort)
- X qsort(&List[bsort], nitems, sizeof(struct entry), compar);
- X
- X List[Index-1].last = 1; /* mark last item for this dir */
- X n_subs = nitems;
- X stmp = Index;
- X
- X /* now walk through, and recurse on directory entries */
- X /* sstep was initialized above */
- X
- X for (i = 0; i < nitems; sstep = &List[stmp - nitems+(++i)]) {
- X if (sstep->dir && (Level < newlevel) && (Xdev || sstep->dev)) {
- X sstep->next = Index;
- X strncpy(sub, sstep->e_name, MAXNAMLEN);
- X tmp = n_subs;
- X Level++;
- X if (chdir(sub) == FAIL) {
- X fprintf(stderr,
- X "xdtree: Cannot change to directory %s/", dir);
- X perror(sub);
- X } else {
- X n_subs += t_search(sub, sstep);
- X if (chdir("..") == FAIL) {
- X fprintf(stderr,
- X "xdtree: %s/%s lacks '..' entry\n",dir, sub);
- X exit(1);
- X }
- X }
- X --Level;
- X if (n_subs - tmp <= 0)
- X sstep->next = 0;
- X else
- X --n_subs;
- X }
- X else
- X sstep->next = 0;
- X }
- X addrs->end = (unsigned)n_subs;
- X return(n_subs);
- }
- X
- /*
- X * comparison routine for qsort
- X */
- X
- compar(a, b)
- struct entry *a, *b;
- {
- X if (!File_dir) /* straight alphabetical */
- X return(strncmp(a->e_name, b->e_name, MAXNAMLEN));
- X
- X /* sort alphabetically if both dirs or both not dirs */
- X
- X if ((a->dir && b->dir) || (!a->dir && !b->dir))
- X return(strncmp(a->e_name, b->e_name, MAXNAMLEN));
- X
- X if (File_dir == FFIRST) { /* sort by files first */
- X if (a->dir)
- X return(GREATER);
- X else
- X return(LESSTHAN);
- X }
- X
- X if (a->dir) /* sort by dir first */
- X return(LESSTHAN);
- X else
- X return(GREATER);
- }
- X
- X
- pt_tree()
- {
- X register int i,j;
- X struct entry *l;
- X struct entry *hdr[DEPTH];
- X int posit[DEPTH]; /* array of positions to print dirs */
- X int con[DEPTH]; /* flags for connecting up tree */
- X char flag = 0; /* flag to leave blank line after dir */
- X struct entry *stack[DEPTH]; /* save positions for changing levels */
- X int top = 0; /* index to top of stack */
- X int count = 1; /* count of line of output */
- X
- X Level = 0; /* initialize Level */
- X
- X /* this loop appends each entry with dashes or spaces, for */
- X /* directories or files respectively */
- X
- X for (i = 0; i < Index; i++) {
- X for (j = 0; j < MAXNAMLEN; j++) {
- X if (!List[i].e_name[j])
- X break;
- X }
- X if (List[i].dir) {
- X for (; j < MAXNAMLEN; j++)
- X List[i].e_name[j] = '-';
- X } else {
- X for (; j < MAXNAMLEN; j++)
- X List[i].e_name[j] = ' ';
- X }
- X }
- X
- X /* adjust the Maxes array according to the flags */
- X
- X for (i = 0; i < DEPTH; i++) {
- X if (Varspaces) {
- X if (Maxes[i] > CLength )
- X Maxes[i] = CLength;
- X } else
- X Maxes[i] = CLength;
- X }
- X
- X /* clear the connective and position flags */
- X
- X for (i = 0; i < DEPTH; i++)
- X con[i] = posit[i] = 0;
- X
- X /* this is the main loop to print the tree structure. */
- X l = &List[0];
- X j = 0;
- X for (;;) {
- X /* directory entry, save it for later printing */
- X if (l->dir != 0 && l->next != 0) {
- X hdr[Level] = l;
- X posit[Level] = count + (l->end + 1)/2 - 1;
- X flag = 1;
- X stack[top++] = l;
- X l = &List[l->next];
- X ++Level;
- X continue;
- X }
- X
- #ifdef STATS
- X do_it_again:
- #endif /* STATS */
- X /* print columns up to our entry */
- X for (j = 0; j < (flag ? Level-1 : Level); j++) {
- X if (!flag && posit[j] && posit[j] <= count) {
- X /* time to print it */
- X if (hdr[j]->e_name[CLength-1] != '-')
- X hdr[j]->e_name[CLength-1] = '*';
- X printf("|-%.*s",Maxes[j],hdr[j]->e_name);
- X posit[j] = 0;
- X if (hdr[j]->last != 0)
- X con[j] = 0;
- X else
- X con[j] = 1;
- #ifdef STATS
- X if (Gflag || Longflg) {
- X if ((i = j+1) <= Level)
- X printf("| %.*s", Maxes[i], Spaces);
- X for (i++; i <= Level; i++) {
- X printf("%c %.*s",
- X (con[i] ? '|' : ' '),
- X Maxes[i], Spaces);
- X }
- X if (!Compact) {
- X printf("%s ", getmode(hdr[j]->e_mode));
- X if (Longflg)
- X printf("%8.8s ",guid(hdr[j]->e_uid));
- X if (Gflag)
- X printf("%8.8s ",ggid(hdr[j]->e_gid));
- X printf("%7ld\n",
- X (hdr[j]->e_size+511L)/512L);
- X } else {
- X printf(" %04o ",hdr[j]->e_mode & 07777);
- X if (Longflg)
- X printf("%5u ", hdr[j]->e_uid);
- X if (Gflag)
- X printf("%5u ", hdr[j]->e_gid);
- X printf("%7ld\n",
- X (hdr[j]->e_size+511L)/512L);
- X }
- X goto do_it_again;
- X }
- #endif /* STATS */
- X } else
- X printf("%c %.*s", (con[j] ? '|' : ' '),
- X Maxes[j], Spaces);
- X }
- X if (flag) { /* start of directory, so leave a blank line */
- X printf(con[j] ? "|\n" : "\n");
- X flag = 0;
- X continue;
- X } else {
- X /* normal file name, print it out */
- X if (l->e_name[CLength-1] != '-' &&
- X l->e_name[CLength-1] != ' ')
- X l->e_name[CLength-1] = '*';
- X printf("|-%.*s",Maxes[Level],l->e_name);
- X if (l->last) {
- X con[j] = 0;
- X } else {
- X con[j] = 1;
- X }
- #ifdef STATS
- X if (Gflag || Longflg) {
- X if (Compact) {
- X printf(" %04o ", l->e_mode & 07777);
- X if (Longflg)
- X printf("%5u ", l->e_uid);
- X if (Gflag)
- X printf("%5u ", l->e_gid);
- X printf("%7ld",
- X (l->e_size+511L)/512L);
- X } else {
- X printf("%s ", getmode(l->e_mode));
- X if (Longflg)
- X printf("%8.8s ",guid(l->e_uid));
- X if (Gflag)
- X printf("%8.8s ",ggid(l->e_gid));
- X printf("%7ld",
- X (l->e_size+511L)/512L);
- X }
- X }
- #endif /* STATS */
- X }
- X printf("\n");
- X
- X if (l->last) {
- X /* walk back up */
- X while (l->last) {
- X --Level;
- X if (--top <= 0)
- X return;
- X l = stack[top];
- X }
- X }
- X l = &l[1];
- X ++count;
- X }
- }
- X
- #ifdef STATS
- X
- char *
- guid(uid)
- short uid;
- {
- X static char tb[10];
- X struct passwd *pswd;
- X
- X pswd = getpwuid(uid);
- X if (pswd == NULL)
- X sprintf(tb,"%u", uid);
- X else
- X sprintf(tb, "%8s", pswd->pw_name);
- X return(tb);
- }
- X
- char *
- ggid(gid)
- short gid;
- {
- X static char tb[10];
- X struct group *grp;
- X
- X grp = getgrgid(gid);
- X if (grp == NULL)
- X sprintf(tb,"%u", gid);
- X else
- X sprintf(tb, "%8s", grp->gr_name);
- X return(tb);
- }
- X
- /* take the mode and make it into a nice character string */
- X
- char *
- getmode(p_mode)
- unsigned short p_mode;
- {
- X static char a_mode[16];
- X register int i = 0, j = 0;
- X
- X a_mode[j++] = ' ';
- X
- X switch (p_mode & S_IFMT) {
- #ifdef S_IFLNK
- X case S_IFLNK:
- X a_mode[j++] = 'l';
- X break;
- #endif /* S_IFLNK */
- X case S_IFDIR:
- X a_mode[j++] = 'd';
- X break;
- #ifdef S_IFMPC /* defined in stat.h if you have MPX files */
- X case S_IFMPC:
- X a_mode[j-1] = 'm';
- X /* FALL THROUGH */
- #endif /* S_IFMPC */
- X case S_IFCHR:
- X a_mode[j++] = 'c';
- X break;
- #ifdef S_IFMPB /* defined in stat.h if you have MPX files */
- X case S_IFMPB:
- X a_mode[j-1] = 'm';
- X /* FALL THROUGH */
- #endif /* S_IFMPB */
- X case S_IFBLK:
- X a_mode[j++] = 'b';
- X break;
- X case S_IFREG:
- X default:
- X a_mode[j++] = (p_mode & S_ISVTX) ? 't' : ' ';
- X break;
- X }
- X a_mode[j++] = ' ';
- X for( i = 0;i<3;i++ ) {
- X a_mode[j++] = (p_mode<<(3*i) & S_IREAD) ? 'r' : '-';
- X a_mode[j++] = (p_mode<<(3*i) & S_IWRITE) ? 'w' : '-';
- X a_mode[j++] = (i<2 && (p_mode<<i & S_ISUID)) ? 's' :
- X ((p_mode<<(3*i) & S_IEXEC ) ? 'x' : '-');
- X a_mode[j++] = ' ';
- X }
- X a_mode[j] = '\0';
- X return(a_mode);
- }
- #endif
- X
- /* like strlen, but returns length up to MAXNAMLEN-1 */
- stln(st)
- register char *st;
- {
- X register int t;
- X
- X for (t=0; t<MAXNAMLEN-1; ++t)
- X if (!st[t])
- X return (++t);
- X return (++t);
- }
- X
- print_date()
- {
- X long now;
- X
- X time(&now);
- X printf ("%s", ctime(&now));
- }
- X
- void
- memory_out()
- {
- X fprintf(stderr, "xdtree: Virtual memory exhausted\n");
- X exit(1);
- }
- X
- /* Allocate `size' bytes of memory dynamically, with error checking. */
- X
- char *
- xmalloc (size)
- unsigned size;
- {
- X char *ptr;
- X
- X ptr = malloc (size);
- X if (ptr == 0 && size != 0)
- X memory_out ();
- X return ptr;
- }
- X
- /* Change the size of an allocated block of memory `ptr' to `size' bytes,
- X with error checking.
- X If `ptr' is NULL, run xmalloc.
- X If `size' is 0, run free and return NULL. */
- X
- char *
- xrealloc (ptr, size)
- char *ptr;
- unsigned size;
- {
- X if (ptr == 0)
- X return xmalloc (size);
- X if (size == 0) {
- X free (ptr);
- X return 0;
- X }
- X ptr = realloc (ptr, size);
- X if (ptr == 0 && size != 0)
- X memory_out ();
- X return ptr;
- }
- /*-------------------------New functions for X windows -----------------*/
- X
- /* Main program to display the tree in an X window */
- X
- show_dtree(parent)
- X Widget parent;
- X
- {
- X Arg wargs[4];
- X struct entry *stack[DEPTH], *branch;
- X int n, top=0, *dir_index;
- X int dir_node=0, dir_count=0, i;
- X Widget parent_node=NULL, *Dir, arc;
- X XmString label_s = NULL;
- X
- X /* Find the number of directories */
- X for(i=0; i < Index; i++)
- X if(List[i].dir == 1) dir_count++;
- X
- X if((Dir = (Widget *) malloc( dir_count * sizeof(Widget))) == NULL){
- X fprintf(stderr,"malloc failure\n");
- X exit(1);
- X }
- X if((dir_index = (int *) malloc(dir_count * sizeof(int))) == NULL) {
- X fprintf(stderr,"malloc failure\n");
- X exit(1) ;
- X }
- X
- X branch = &List[0];
- X
- X if(dir_count == 1 && branch->next == 0) {
- X if(All == 0) {
- X fprintf(stderr,"No subdirectories under directory %s\n",
- X branch->e_name);
- X fprintf(stderr,"You may want to try the -ap option\n");
- X }
- X else fprintf(stderr,"No files under directory %s\n",
- X branch->e_name);
- X exit(0);
- X }
- X
- X /* Distinguish between directories and files */
- X
- X for(;;) {
- X if(branch->dir != 0 && branch->next != 0) {
- X dir_index[top] = dir_node;
- X stack[top++] = branch;
- X n=0;
- X XtSetArg(wargs[n], XtNsuperNode,parent_node); n++;
- X label_s = XmStringCreateLtoR(branch->e_name,
- X XmSTRING_DEFAULT_CHARSET);
- X XtSetArg(wargs[n], XmNlabelString,label_s); n++;
- X Dir[dir_node] = XmCreatePushButton(parent,"dir",
- X wargs,n);
- X XtManageChild(Dir[dir_node]);
- X XtAddCallback(Dir[dir_node],XmNactivateCallback,
- X clickB, branch);
- X
- X branch = &List[branch->next];
- X parent_node = Dir[dir_node++];
- X continue;
- X }
- X create_file_node(parent,branch,parent_node);
- X if(branch->last) {
- X while(branch->last) {
- X if(--top <= 0 ) {
- X free(Dir);
- X free(dir_index);
- X return;
- X }
- X branch = stack[top];
- X parent_node = Dir[dir_index[top-1]];
- X }
- X }
- X branch = &branch[1];
- X }
- }
- /* Function that creates a widget for a node. Three types are available,
- X dir, for directories , file, for files, and sym_link for
- X symbolic links
- */
- create_file_node(pparent,bbranch,nnode)
- X Widget pparent, nnode;
- X struct entry *bbranch;
- {
- X Widget w, arc;
- X Arg wargs[4];
- X int n;
- X char *win_type;
- X XmString label_s = NULL;
- X int Gflag=1; /* this is a gadget */
- X
- X
- X n=0;
- X label_s = XmStringCreateLtoR(bbranch->e_name,
- X XmSTRING_DEFAULT_CHARSET);
- X XtSetArg(wargs[n], XmNlabelString,label_s); n++;
- X
- X /* Check the type of the node */
- X if(bbranch->dir == 1) {
- X win_type = "dir";
- X Gflag = 0;
- X }
- #ifdef STATS
- X else if(strncmp(" l",getmode(bbranch->e_mode),2) == 0)
- X {win_type = "sym_link"; Gflag = 0;}
- #endif /* STATS */
- X else win_type = "file";
- X XtSetArg(wargs[n], XtNsuperNode, nnode); n++;
- X w = XmCreatePushButton(pparent, win_type, wargs, n);
- X XtManageChild(w);
- X XtAddCallback(w,XmNactivateCallback,clickB,bbranch);
- X
- }
- /* Function that creates the pull-down menu when someone clicks on the
- X active node of the tree.
- */
- X
- show_menu(pparent, bbranch, top_widget)
- X Widget pparent,top_widget;
- X struct entry *bbranch;
- {
- X Widget menu ;
- X Widget submenu_mode,submenu_print;
- X Widget print, S_toggle,plabel,H_toggle,g_toggle;
- X int i,n;
- X char *mode_name;
- X Arg wargs[4];
- X Arg arg[15];
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNtopWidget, top_widget); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X submenu_mode = XtCreateManagedWidget("menu_file",
- X xmRowColumnWidgetClass, pparent, arg,n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftWidget, submenu_mode); n++;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- X XtSetArg(arg[n], XmNtopWidget, top_widget); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X submenu_file = XtCreateManagedWidget("menu_mode",
- X xmRowColumnWidgetClass, pparent, arg,n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftWidget, submenu_file); n++;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- X XtSetArg(arg[n], XmNtopWidget, top_widget); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X submenu_dir = XtCreateManagedWidget("menu_dir",
- X xmRowColumnWidgetClass, pparent, arg,n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftWidget, submenu_dir); n++;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
- X XtSetArg(arg[n], XmNtopWidget, top_widget); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X submenu_print = XtCreateManagedWidget("printer",
- X xmRowColumnWidgetClass, pparent, arg,n);
- X
- X options = XtCreateManagedWidget("options",xmLabelWidgetClass,
- X submenu_mode, wargs, 1);
- X w_print(options, bbranch->e_name);
- X
- X plabel = XtCreateManagedWidget("plabel",xmLabelWidgetClass,
- X submenu_print, wargs, 1);
- X w_print(plabel, "Print-Tree Options");
- X /*
- X boxes[0] = XtCreateManagedWidget("title",xmLabelWidgetClass,
- X submenu_mode, NULL,0);
- X */
- X XtCreateManagedWidget("separator2",xmSeparatorWidgetClass,
- X submenu_mode, NULL,0);
- X /*
- X XtCreateManagedWidget("separator",xmSeparatorWidgetClass,
- X submenu_print, NULL,0);
- X */
- #ifdef STATS
- X for(i = 1; i < 4 ; i++)
- X boxes[i] = XtCreateManagedWidget("id",xmLabelWidgetClass,
- X submenu_mode, NULL,0);
- X boxes[11] = XtCreateManagedWidget("id",xmLabelWidgetClass,
- X submenu_mode, NULL,0);
- X button_print(bbranch); /* print the labels on the menu */
- X
- X
- X
- X /* Create sub-menus */
- X
- #endif /*STATS */
- X
- X file_menu = XtCreateManagedWidget("File Options",
- X xmLabelWidgetClass, submenu_file, NULL,0);
- X dir_menu = XtCreateManagedWidget("Directory Options",
- X xmLabelWidgetClass, submenu_dir, NULL,0);
- X
- X /* If it is a file */
- X /*submenu_file = XtCreateManagedWidget(menu, "filesubmenu", NULL, 0);*/
- X
- X boxes[4] = XtCreateManagedWidget("view",xmPushButtonWidgetClass,
- X submenu_file, NULL,0);
- X XtAddCallback(boxes[4], XmNactivateCallback,view, NULL);
- X boxes[5] = XtCreateManagedWidget("topview",
- X xmPushButtonWidgetClass, submenu_file, NULL,0);
- X XtAddCallback(boxes[5], XmNactivateCallback,view, NULL);
- X boxes[6] = XtCreateManagedWidget("edit",
- X xmPushButtonWidgetClass, submenu_file, NULL,0);
- X XtAddCallback(boxes[6], XmNactivateCallback,do_menu, NULL);
- X boxes[7] = XtCreateManagedWidget("print",
- X xmPushButtonWidgetClass, submenu_file, NULL,0);
- X XtAddCallback(boxes[7], XmNactivateCallback,do_menu, NULL);
- X
- X /* if it a directory */
- X boxes[8] = XtCreateManagedWidget("show subtree",
- X xmPushButtonWidgetClass, submenu_dir, NULL,0);
- X XtAddCallback(boxes[8], XmNactivateCallback,do_menu, NULL);
- X boxes[9] = XtCreateManagedWidget("list files",
- X xmPushButtonWidgetClass, submenu_dir, NULL,0);
- X XtAddCallback(boxes[9], XmNactivateCallback,do_menu, NULL);
- X boxes[10] = XtCreateManagedWidget("list ../",
- X xmPushButtonWidgetClass, submenu_dir, NULL,0);
- X XtAddCallback(boxes[10], XmNactivateCallback,do_menu, NULL);
- X
- X /* print command */
- X print = XtCreateManagedWidget("print tree",
- X xmPushButtonWidgetClass, submenu_print, NULL,0);
- X XtAddCallback(print, XmNactivateCallback,print_tree, NULL);
- X
- X S_toggle = XtCreateManagedWidget("Print Stats. (-S)",
- X xmToggleButtonWidgetClass, submenu_print, NULL,0);
- X XtAddCallback(S_toggle, XmNvalueChangedCallback,stoggle, NULL);
- X
- X H_toggle = XtCreateManagedWidget("Print Header (-H)",
- X xmToggleButtonWidgetClass, submenu_print, NULL,0);
- X XtAddCallback(H_toggle, XmNvalueChangedCallback,htoggle, NULL);
- X
- X g_toggle = XtCreateManagedWidget("Use Group Name (-g)",
- X xmToggleButtonWidgetClass, submenu_print, NULL,0);
- X XtAddCallback(g_toggle, XmNvalueChangedCallback,gtoggle, NULL);
- }
- /* Not used here, but may be useful in the future !!! */
- /* Copied from D. Young's book */
- /*
- void post_menu_handler(w, menu, event)
- X Widget w, menu;
- X XEvent *event;
- {
- X Arg wargs[10];
- X int button;
- X
- X XtSetArg(wargs[0], XmNwhichButton, &button);
- X XtGetValues(menu, wargs, 1);
- X if(event->xbutton.button == button) {
- X XmMenuPosition(menu, event);
- X XtManageChild(menu);
- X }
- }
- */
- /* Quick and dirty way to view a file in a pop-up window
- X Speed may improve, if one reads and displays page by page
- X No check to see if the file is binary
- */
- void view(w, call_mydata, call_data)
- X Widget w;
- X caddr_t call_data, call_mydata;
- X
- {
- X struct entry *branch;
- X char *filename[MAXPATHLEN+1];
- X struct stat statbuf; /* Information on a file. */
- X int file_length; /* Length of file. */
- X unsigned char * file_string; /* Contents of file. */
- X FILE *fp = NULL;
- X Widget text, toplevel2, sw2, button, frame, outer;
- X Widget title;
- X XmString name_string = NULL;
- X char *button_name = NULL;
- X int topflag=0;
- X Arg wargs[10];
- X Arg arg[10];
- X int n=0;
- X
- X branch = file_pointer;
- X /* find which button called us */
- X XtSetArg(wargs[0], XmNlabelString, &name_string);
- X XtGetValues(w,wargs,1);
- X XmStringGetLtoR(name_string,XmSTRING_DEFAULT_CHARSET,&button_name);
- X if(strcmp("topview",button_name) == 0) topflag = 1;
- X
- X /* find first the correct path */
- X
- X strncpy(filename,branch->path_name,MAXPATHLEN);
- X strcat(filename,"/");
- X strcat(filename,branch->e_name);
- X
- X
- X if ((fp = fopen(filename, "r")) == NULL) {
- X fprintf(stderr,"Can't open file name %s\n",filename);
- X return;
- X }
- X if (stat(filename, &statbuf) == 0)
- X file_length = statbuf.st_size;
- X else
- X file_length = 1000000; /* arbitrary file length */
- X
- X /* read the file string */
- X
- X if(topflag == 1 && file_length >= 2000 ) file_length = 2000;
- X
- X file_string = (unsigned char *) XtMalloc((unsigned)file_length);
- X fread(file_string, sizeof(char), file_length, fp);
- X
- X if (fclose(fp) != NULL) fprintf(stderr, "Warning: unable to close file.\n");
- X
- X /* Create another pop-pup top-shell with a MainWindow */
- X
- X toplevel2 = XtCreateApplicationShell("Dtreef",topLevelShellWidgetClass,
- X NULL,0);
- X
- X n=0;
- X outer = XtCreateManagedWidget(NULL, xmFormWidgetClass,
- X toplevel2, wargs, n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNlabelString, XmStringCreate("Quit",
- X XmSTRING_DEFAULT_CHARSET)); n++;
- X button = XtCreateManagedWidget("button", xmPushButtonWidgetClass,
- X outer, arg, n);
- X
- X XtAddCallback(button,XmNactivateCallback,quit_b_pop,toplevel2);
- X
- X n=0;
- X XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNlabelString, XmStringCreate(filename,
- X XmSTRING_DEFAULT_CHARSET)); n++;
- X title = XtCreateManagedWidget("title",
- X xmLabelWidgetClass, outer, arg,n);
- X
- X n=0;
- X XtSetArg(arg[n], XmNtopWidget, button); n++;
- X XtSetArg(arg[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
- X XtSetArg(arg[n], XmNleftAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNrightAttachment, XmATTACH_FORM); n++;
- X XtSetArg(arg[n], XmNshadowType, XmSHADOW_OUT); n++;
- X XtSetArg(arg[n], XmNbottomAttachment, XmATTACH_FORM); n++;
- X frame = XtCreateManagedWidget("frame", xmFrameWidgetClass,
- X outer, arg,n);
- X
- X n=0;
- X XtSetArg(wargs[n], XmNscrollingPolicy, XmAUTOMATIC); n++;
- X sw2 = XtCreateManagedWidget("swindowf",
- X xmScrolledWindowWidgetClass,frame, wargs,n);
- X
- X
- X /* Create Text widget */
- X n=0;
- X XtSetArg (wargs[n], XmNcolumns, 85); n++;
- X XtSetArg (wargs[n], XmNeditable, FALSE); n++;
- X
- X text = XmCreateText(sw2, "text", wargs, n);
- X
- X /* added the file string to the text widget */
- X
- X XmTextSetString(text, file_string);
- X if(file_string != NULL) XtFree(file_string);
- X if(name_string != NULL) XtFree(name_string);
- X
- X /* Poput the text file */
- X
- X XtPopup(toplevel2,XtGrabNone);
- X XtManageChild(text);
- }
- X
- /* CallBack function of the quit button on a pop-up window */
- X
- void quit_b_pop(w, topshell, call_data)
- X Widget w;
- X Widget topshell;
- X caddr_t call_data;
- {
- X XtPopdown(topshell);
- }
- X
- /* function that forks a command from the menu */
- /* Needs work!!!!!
- */
- void do_menu(w,call_mydata,call_data)
- X Widget w;
- X caddr_t call_data, call_mydata;
- X
- {
- X struct entry *branch;
- X char *filename[MAXPATHLEN+1];
- X char *topdir[MAXPATHLEN+1];
- X XmString name_string = NULL;
- SHAR_EOF
- true || echo 'restore of xdtree.c failed'
- fi
- echo 'End of part 1'
- echo 'File xdtree.c is continued in part 2'
- echo 2 > _shar_seq_.tmp
- exit 0
- --
- ---
- Senior Systems Scientist mail: dcmartin@msi.com
- Molecular Simulations, Inc. uucp: uunet!dcmartin
- 796 North Pastoria Avenue at&t: 408/522-9236
-