From:	CRDGW2::CRDGW2::MRGATE::"SMTP::CRVAX.SRI.COM::RELAY-INFO-VAX"  7-JUN-1989 14:35
To:	MRGATE::"ARISIA::EVERHART"
Subj:	MAINT -- Full Screen File/Directory Maintenance (Part 6 of 11)

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Wed,  7 JUN 89 07:30:46 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Wed, 7 Jun 89 07:11:03 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA18263; Wed, 7 Jun 89 06:43:32 -0700
Received: from USENET by ucbvax.Berkeley.EDU with netnews
	for info-vax@kl.sri.com (info-vax@kl.sri.com)
	(contact usenet@ucbvax.Berkeley.EDU if you have questions)
Date: 7 Jun 89 12:48:03 GMT
From: peirce@gumby.wisc.edu  (Leonard J. Peirce)
Organization: Western Michigan University, Kalamazoo, MI
Subject: MAINT -- Full Screen File/Directory Maintenance (Part 6 of 11)
Message-Id: <741@gumby.cc.wmich.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

+-+-+-+ Beginning of part 6 +-+-+-+
Vstatic`009 ULONG`009  key;`009`009`009/* key size entry for sorting`009  `032
X   */
X
X
X   if(m < n)
X   `123
X      i = m;
X      j = n + 1;
X      key = baseptr[m].size;
X
X      for(;;)
X      `123
X`009 do
X`009 `123
X`009    ++i;
X`009 `125
X`009 while(baseptr[i].size < key);
X
X`009 do
X`009 `123
X`009    --j;
X`009 `125
X`009 while(baseptr[j].size > key);
X
X`009 if(i < j)
X`009 `123
X`009    /* swap the file entries */
X
X`009    swap_entries(&baseptr[i],&baseptr[j]);
X`009 `125
X`009 else
X`009    break;
X
X      `125 /* for(;;) */
X
X      swap_entries(&baseptr[m],&baseptr[j]);
X      size_qsort(m,j-1);
X      size_qsort(j+1,n);
X
X   `125 /* if(m < n) */
X
X   return;
X
X`125`009/*** size_qsort ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009date_qsort
X
X  Purpose:`009Sort the directory entries by last access date.
X
X`009`009Algorithm for quicksort from "Fundamentals of Data Structures",
X`009`009Ellis Horowitz and Sartaj Sahni, page 137.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009baseptr`009`009`009`009`009X
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void date_qsort(m,n)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister short`009  m,`009`009`009/* lower-bound of sub-array to be     */
X`009`009`009`009`009/* sorted`009`009`009      */
X`009`009  n;`009`009`009/* upper-bound of sub-array to be     */
X`009`009`009`009`009/* sorted`009`009`009      */
X
X`123`009/*** date_qsort ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister long`009  i,`009`009`009/* loop and array index`009`009      */
X`009`009  j;`009`009`009/*  "    "    "     "`009`009      */
Xstatic`009 long`009  key[2];`009`009/* key size entry for sorting`009      */
X
X
X   if(m < n)
X   `123
X      i = m;
X      j = n + 1;
X      key[0] = baseptr[m].time[0];
X      key[1] = baseptr[m].time[1];
X
X      for(;;)
X      `123
X`009 do
X`009 `123
X`009    ++i;
X`009 `125
X`009 while(time_cmp(baseptr[i].time,key) == -1);
X
X`009 do
X`009 `123
X`009    --j;
X`009 `125
X`009 while(time_cmp(baseptr[j].time,key) == 1);
X
X`009 if(i < j)
X`009 `123
X`009    /* swap the file entries */
X
X`009    swap_entries(&baseptr[i],&baseptr[j]);
X`009 `125
X`009 else
X`009    break;
X
X      `125 /* for(;;) */
X
X      swap_entries(&baseptr[m],&baseptr[j]);
X      size_qsort(m,j-1);
X      size_qsort(j+1,n);
X
X   `125 /* if(m < n) */
X
X   return;
X
X`125`009/*** date_qsort ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009time_cmp
X
X  Purpose:`009Compare two quadword time values.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009  0`009`009`009time1 = time2
X`009 -1`009`009`009time1 < time2
X`009  1`009`009`009time1 > time2
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic short time_cmp(time1,time2)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 long`009  time1[],`009`009/* first quadword time value`009      */
X`009`009  time2[];`009`009/* second quadword time value`009      */
X
X`123`009/*** time_cmp ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xstatic`009 long`009  temp[2];`009`009/* for saving the result`009      */
X  `032
V   LIB$SUBX(time1,time2,temp);`009`009/* subtract time1 from time2`009      *
X/
X
X   if(temp[1] < 0L)
X      return(-1);
X   else if(temp[1] == 0L && temp[0] == 0L)
X      return(0);
X
X   return(1);
X
X`125`009/*** time_cmp ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009swap_entries
X
X  Purpose:`009Swap two file entries.
X
X  Global variables:
X
X`009Name`009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void swap_entries(a,b)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ENT_DEF  *a,`009`009`009/* first to be swapped `009`009      */
X`009`009  *b;`009`009`009/* other entry to be swapped`009      */
X
X`123`009/*** swap_entries ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Vstatic`009 ENT_DEF  temp;`009`009`009/* temporary entry for swapping`009 `032
X    */
X
X   memcpy((void *) &temp,(void *) a, sizeof(temp));
X   memcpy((void *) a,(void *) b, sizeof(temp));
X   memcpy((void *) b,(void *) &temp, sizeof(temp));
X
X`125`009/*** swap_entries ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009check_marks
X
X  Purpose:`009Check to see if there are any marks in the current directory.
X
X  Global variables:
X
X`009Name `009`009`009Examine/Modify/Use/Read/Write
X`009----`009`009`009-----------------------------
X`009none
X
X  Return Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009TRUE`009`009`009marks exist in current directory
X`009FALSE`009`009`009no marks in current directory
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic USHORT check_marks(ent,num_files)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister ENT_DEF  *ent;`009`009`009/* pointer to current file entry      */
Vregister short`009  num_files;`009`009/* number of files in directory`009`032
X     */
X
X`123`009/*** check_marks ***/
X
X   while(num_files--)`009`009`009/* check all entries if necessary     */
X   `123
X      if(ent->command)`009`009`009/* command for this file?`009      */
X`009 return(TRUE);`009`009`009/* yes, no need to check any more     */
X
X      ent++;`009`009`009`009/* nope, go to next entry`009      */
X   `125
X
X   return(FALSE);
X
X`125`009/*** check_marks ***/
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAINT.CLD"
$ CHECKSUM_IS = 539007867
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
Xdefine type sort_options
X`009keyword`009date
X`009keyword`009filename
X`009keyword`009size
X`009keyword type
X
Xdefine verb maint
X`009image sys$system:maint.exe
X`009parameter p1,value(type=$infile),label=infile
X`009qualifier confirm`009placement=global
X`009qualifier date`009`009placement=global
X`009qualifier full`009`009placement=global
X`009qualifier help`009`009placement=global
X`009qualifier protection`009placement=global
X`009qualifier size`009`009placement=global
X`009qualifier sort`009`009placement=global,value(type=sort_options)
X`009qualifier text`009`009placement=global
X`009qualifier wide`009`009placement=global
X`009disallow full and date
X`009disallow full and size
X`009disallow full and protection
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAINT.H"
$ CHECKSUM_IS = 53507943
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X#ifndef MAINT_H
V/****************************************************************************
X**
V*****************************************************************************
X**
X
X   Installation:  Western Michigan University Academic Computer Center
X
X   System:`009Directory/File System Maintenance (MAINT)
X `032
X   Header name:`009maint.h
X
X   Version=01`009Level=01`00908/12/87`009Leonard J. Peirce
X
X   Purpose:  Header file for the MAINT program.  This header file should
X`009     only be used by MAINT as it would be of no use to any other
X`009     program.
X
X   Version=01`009Level=02`00910/06/88`009Leonard J. Peirce
X
X   Purpose:  Changes made for Version 1.5.  See MAINT.C for more information.
X
X   Other information:`009none
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
X#define MAINT_H 1`009`009`009/* to prevent multiple inclusion      */
X#define WMUACC
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*                        # I N C L U D E   F I L E S                    `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X#ifdef WMUACC
X#include utype
X#else
X#include "utype.h"
X#endif
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*                             # D E F I N E S                           `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X#define EXTERNAL_HLB`009`009`009/* our own EXTERNAL help library      */
X#define SMG$_EOF 1213442`009`009/* missing SMG definition`009      */
X
X#define MAX_NODE_ROW 19`009`009`009/* max. number of file rows`009      */
X#define MAX_NODE_COL 8`009`009`009/* max. number of file columns`009      */
X#define DEV_MAX 255`009`009`009/* max. length of device name`009      */
X#define FLAG_CHAR '*'`009`009`009/* long filename flag character`009      */
X
X#define DIR_INFO_ROWS 2`009`009`009/* # of rows in page # display`009      */
X#define MAIN_ROWS 20`009`009`009/* # of rows in main display`009      */
X#define WORK_ROWS 22`009`009`009/* # of rows in work display`009      */
X#define OPT_INFO_ROWS 2`009`009`009/* # of rows in options/stats display */
X
X#define DIR_INFO_BASE_ROW 1`009`009/* base row when pasted`009`009      */
X#define DIR_INFO_BASE_COL 1`009`009/* base col when pasted`009`009      */
X#define MAIN_BASE_ROW 3
X#define MAIN_BASE_COL 1
X#define WORK_BASE_ROW 3
X#define WORK_BASE_COL 1
X#define OPT_INFO_BASE_ROW 23
X#define OPT_INFO_BASE_COL 1
X
X#define CANT_OPEN -1`009`009`009/* can't open file to display it      */
V#define CANT_DISPLAY -2`009`009`009/* can't display file on screen`009      *
X/
X#define EMPTY_FILE -3`009`009`009/* selected file is empty`009      */
X#define BAD_FILE -4`009`009`009/* file format invalid`009`009      */
X#define DONT_CREATE -5`009`009`009/* do not create file`009`009      */
X#define NO_FILE -6`009`009`009/* file does not exist`009`009      */
X#define NEW_FILE -7`009`009`009/* new file had to be created`009      */
X#define BAD_SCREEN_NO -8`009`009/* bad screen number read in`009      */
X#define DISPLAY_TEXT 1`009`009`009/* text descriptors to be displayed   */
X#define SLOT_OVF 2`009`009`009/* text descriptor overflows slot     */
X
X`009`009`009`009`009/**    return codes for proc_dir()   **/
X#define RECALL_PROC 1`009`009`009/* force proc_dir() to be recalled    */
X#define EMPTY_DIR 2`009`009`009/* selected directory is empty`009      */
X
X#define PROT_MAX 19`009`009`009/* max. length of protection string   */
X#define DATE_MAX 17`009`009`009/* max. length of date/time string    */
X#define NAME_MAX 19`009`009`009/* max. length of displayed filename  */
X#define SIZE_MAX 6`009`009`009/* max. length of filesize string     */
X#define FULL_MAX 65`009`009`009/* max. length of full info string    */
X#define SCR_MAX 132`009`009`009/* maximum screen width`009`009      */
X#define MESS_MAX 255`009`009`009/* max. length of broadcast message   */
X#define STR_MAX 255`009`009`009/* max. length of help input line     */
X#define FILENAME_MAX 10`009`009`009/* max. length of displayed filename  */
X#define TYPE_MAX 3`009`009`009/* max. length of displayed filetype  */
X#define VERSION_MAX 3`009`009`009/* max. length of displayed version   */
X#define SPEC_MAX 80`009`009`009/* max. length of filename`009      */
X#define FULL_SPEC_MAX 255`009`009/* max. length of full file spec      */
X#define COMMAND_MAX 3`009`009`009/* max. number of commands per file   */
X#define TEXT_MAX 40`009`009`009/* max. length of text descriptor     */
X#define DIR_TEXT_MAX 60`009`009`009/* max. length of directory text desc */
X#define DATE_TIME_MAX 23`009`009/* max. length of a date/time string  */
X#define BUF_MAX 16384`009`009`009/* buffer size for block mode copying */
X#define PAGE_NO_MAX 4`009`009`009/* max. digits in screen number`009      */
X#define ACLBUF_MAX 512`009`009`009/* max. length of ACL binary buffer   */
X#define RESP_MAX 74`009`009`009/* max. length of "Topic ?" response  */
X#define PROT_INP_MAX 60`009`009`009/* max. length of protect str read in */
X`009`009`009`009`009/* from the screen`009`009      */
X
X#define IN_REC_SIZE 512`009`009`009/* size of input record buffer`009      */
X#define TEXT_REC_MAX 112`009`009/* max. length of text descriptor rec */
X#define FUDGE_FACTOR 35`009`009`009/* multiplied by number of elements   */
X`009`009`009`009`009/* needed to get the size of the      */
X`009`009`009`009`009/* memory pool to allocate`009      */
X
V#define TEXT_FILE "MAINT.TDF"`009`009/* name of text descriptor file`009 `032
X    */
X
X#define DELETE 'd'`009`009`009/* file command definitions`009      */
X#define RENAME 'r'
X#define COPY 'c'
X#define PROTECT 'p'
X#define TEXT 't'
X`009`009`009`009`009/* /SORT option flag values`009      */
X#define FILENAME 0`009`009`009/* sort by filename`009`009      */
X#define TYPE 1`009`009`009`009/* sort by file type`009`009      */
X#define SIZE 2`009`009`009`009/* sort by file size`009`009      */
X#define DATE 3`009`009`009`009/* sort by date`009`009`009      */
X
X#define SYSTEM_READ 0x1`009`009`009/* protection field bit masks`009      */
X#define SYSTEM_WRITE 0x2
X#define SYSTEM_EXECUTE 0x4
X#define SYSTEM_DELETE 0x8
X
X#define OWNER_READ 0x10
X#define OWNER_WRITE 0x20
X#define OWNER_EXECUTE 0x40
X#define OWNER_DELETE 0x80
X
X#define GROUP_READ 0x100
X#define GROUP_WRITE 0x200
X#define GROUP_EXECUTE 0x400
X#define GROUP_DELETE 0x800
X
X#define WORLD_READ 0x1000
X#define WORLD_WRITE 0x2000
X#define WORLD_EXECUTE 0x4000
X#define WORLD_DELETE 0x8000
X
V#define TPU$_NORMAL 0x3F2B091`009`009/* can't find it anywhere.....`009  `032
X   */
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*          S T R U C T U R E S ,   U N I O N S ,   T Y P E D E F S      `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
Vtypedef`009 struct`009  DATE_TYPE `123`009`009/* for overlaying date values`0
X09      */
X`009 ULONG`009  left,`009`009`009/* left 32-bits of date/time value    */
X`009`009  right;`009`009/* right 32-bits`009`009      */
X`125 DATE_DEF;
X
Vtypedef`009 struct`009  NODE_TYP `123`009`009/* screen position node`009`009
X      */
X`009 short`009  left_row,`009   `009/* row-coordinate for node array      */
X`009`009  left_col,`009`009/* column-coordinate for node array   */
X`009`009  right_row,`009`009/* row-coordinate for node array      */
X`009`009  right_col,`009`009/* column-coordinate for node array   */
X`009`009  down_row,`009`009/* row-coordinate for node array      */
X`009`009  down_col,`009`009/* column-coordinate for node array   */
X`009`009  up_row,`009`009/* row-coordinate for node array      */
X`009`009  up_col,`009`009/* column-coordinate for node array   */
X`009`009  row,`009`009`009/* cursor row coordinate for node     */
X`009`009  column;`009`009/* cursor column coordinate for node  */
X`125 NODE_DEF;
X
Vtypedef`009 struct`009  ARG_TYP `123`009`009/* run-time argument flags`009
X      */
X`009 short`009  sort,`009`009`009/* wants files sorted`009`009      */
X`009`009  size,`009`009`009/* wants size field included`009      */
X`009`009  prot,`009`009`009/* wants protection field included    */
X`009`009  date,`009`009`009/* wants date field included`009      */
X`009`009  def,`009`009`009/* wants just default info`009      */
X`009`009  full,`009`009`009/* wants all (size,date,prot)`009      */
X`009`009  wide,`009`009`009/* wants 132-column mode`009      */
X`009`009  confirm,`009`009/* wants to be asked before Xecuting  */
X`009`009  text_startup,`009`009/* set if /TEXT on command line`009      */
X`009`009  text;`009`009`009/* wants text descriptors included    */
X`125 ARG_DEF;
X
Vtypedef`009 struct`009  COM_TYP `123`009`009/* file command definition type`0
X09      */
X`009 char`009  *copy_name,`009`009/* new filename for copying`009      */
X`009`009  *ren_name,`009`009/* new filename for renaming`009      */
X`009`009  *text;`009`009/* text descriptor string`009      */
X`009 USHORT`009  prot;`009`009`009/* protection value`009`009      */
X`009 short`009  copy_len,`009`009/* max. length of copy filename str.  */
X`009`009  ren_len,`009`009/* max. length of rename filename str */
X`009`009  text_len;`009`009/* max. length of text string`009      */
X`009 char`009  comm_text,`009`009/* text descriptor for file`009      */
X`009`009  comm_del,`009`009/* file is to be deleted`009      */
X`009`009  comm_prot,`009`009/* new protection for file`009      */
X`009`009  comm_copy,`009`009/* file is to be copied`009`009      */
X`009`009  comm_ren;`009`009/* file is to be renamed`009      */
X`009 char`009  dummy[3];`009`009/* pad-out; might not be necessary    */
X`125 COM_DEF;
X
Vtypedef`009 struct`009  ENT_TYP `123`009`009/* file entry definition type`009
X      */
X`009 COM_DEF  *command;`009`009/* commands for file`009`009      */
X  `009 char`009  *filename,`009`009/* real filename`009`009      */
X`009`009  *prot_str,`009`009/* file protection string`009      */
X`009`009  *date_str,`009`009/* date/time string`009`009      */
X`009`009  *text;`009`009/* text descriptor`009`009      */
X`009 ULONG `009  size,`009`009`009/* in blocks`009`009`009      */
X`009`009  time[2];`009`009/* quadword time value`009`009      */
X`009 USHORT`009  prot;`009`009`009/* integer value of protection`009      */
V`009 char`009  scr_name[NAME_MAX+1],`009/* filename displayed on screen`009
X      */
X`009`009  curdir;`009`009/* set if file in current directory   */
X`009 char`009  dummy[1];`009`009/* make length of structure a multi-  */
X`009`009`009`009`009/* ple of 4 to make things easier     */
X`125 ENT_DEF;
X
Vtypedef`009 struct`009  POOL_TYP `123`009`009/* memory pool node structure`00
X9      */
X`009 char`009  *ptr,`009`009`009/* pointer to next byte in pool`009      */
X`009`009  *first;`009`009/* pointer to beginning of pool`009      */
Vstruct`009 POOL_TYP *next_pool;`009`009/* pointer to next memory pool`009`032
X     */
X`009 long`009  remaining,`009`009/* # of remaining bytes in pool`009      */
X`009`009  length;`009`009/* original length of pool`009      */
X`125 POOL_DEF;
X
Vtypedef`009 struct`009  OPT_TYPE `123`009`009/* displayed options definition`
X009      */
X`009 char`009  *keystr,`009`009/* keystroke for command`009      */
X`009  `009  *remaining,`009`009/* rest of chars in command`009      */
X`009`009  key_len,`009`009/* length of keystroke for command    */
X`009`009  rem_len,`009`009/* length of rest of chars in command */
X`009`009  spaces;`009`009/* number of spaces after command def */
X`125 OPT_DEF;
X
Vtypedef`009 struct`009  UIC_TYPE `123`009`009/* for overlaying xab$l_uic`009
X      */
X`009 USHORT`009  member,`009`009/* member part of UIC`009`009      */
X`009`009  group;`009`009/* group part of UIC`009`009      */
X`125 UIC_DEF;
X
Vtypedef`009 struct`009  `123`009`009`009/* summary info of directory entries
X  */
X`009 ENT_DEF  *ptr;`009`009`009/* pointer to directory info`009      */
X`009 short`009  num_file;`009`009/* number of files in directory`009      */
X`125 DIR_SUMM;
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*   E X T E R N A L   D E F I N I T I O N S   &   D E C L A R A T I O N S
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*     S T A T I C   D E F I N I T I O N S   &   D E C L A R A T I O N S `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X#endif
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAINT.HLP"
$ CHECKSUM_IS = 238376976
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
X1 MAINT
X! MAINT.HLP
X! Written by:`009Leonard J. Peirce`00908/12/87
X!
X
XMAINT is a full-screen File Maintenance utility that can be used to
Xmaintain directories/files.  Directories are presented to the user in a
Xseries of one or more screens and allows the user the opportunity to work
Xwith entire directories at one time instead of working with a few files
Xand having to do a DIRECT to see the current state of the directory.
X
XWith the entire directory accessible it is possible to perform commands
Xon files.  This means that the command for the file or directory is
Xspecified but the action is not actually performed until the user
X"executes" the commands in the directory.  This gives the user ample
Xopportunity to change his/her mind.
X
XThe following functions are available in MAINT:
X
X   1) delete files/directories
X   2) copy files
X   3) rename files/directories
X   4) protect files/directories
X   5) edit an ACL for a file/directory
X   6) list a file's contents to the screen
X   7) change to a subdirectory
X   8) get full directory information on a file
X   9) search for a specific file in a directory
X  10) suspend MAINT and return to DCL level, either indefinitely or just
X      to execute one command
X  11) create extended textual descriptors for files and directories
X  12) access on-line help
X
XMAINT works within the directory structure provided by VMS, that of a tree.
XThis being the case, the first directory that the program sees is considered
Xthe 'root' of the session and is the highest-level directory that is access-
Xible for the duration of the session.
X
XThere is no limitation on the number of files in a directory that MAINT can
Xhandle other than the amount of memory that it can request from the operating
Xsystem.
X
XTo invoke MAINT, the syntax for the command is:
X
X   $ MAINT/qualifier(s) [start-spec]
X
X   where
X
X      [start-spec]        optional starting root directory and optional
X                          starting file specification; if not specified,
X                          the current default directory will be used
X                          and all files in the directory will be included.
X                          A file specification will only be in force for
X                          the first level of the session; if a subdirectory
X                          is selected, all files in the subdirectory will
X                          be included.
X2 Qualifiers
X/CONFIRM
X
X  Confirm that the commands for the current directory are to be done when
X  an eXecute command is issued.
X
X/DATE
X `032
X  Include the creation date for all files.
X
X/FULL
X
X  /FULL
X
X  Equivalent to /DATE/SIZE/PROTECTION.
X
X/HELP
X
X  Invoke the VMS Help utility for MAINT. `032
X
X/PROTECTION
X
X  Include the protection string for each file
X
X/SIZE
X
X  Include the file size of each file in number of blocks used.
X
X/SORT
X
X  /SORT=[option]
X
X  The files can be sorted by a number of different field.  The default is
X  FILENAME.  Other options that can be specified include:  SIZE (size of the
X  files in blocks) and FILENAME (default).
X
X  The /SORT option can impact the performance of MAINT, especially for large
X  directories.
X
X/TEXT
X
X  Use extended textual descriptors if the file MAINT.TDF
X  exists in the selected directory.
X
X/WIDE
X
X  /WIDE
X
X  Use 132-column mode (if available for terminal), allowing more information
X  to be included for each screen of the directory listing.
X2 Display_information
XFilenames on the Main Display have maximum field widths for the filename
Xpart, the filetype, and the version number.  This is done to make it easier
Xto format the screen.
X
XThe maximum field widths for the three parts of the file name are
X
X   filename`009maximum of 10 characters
X   filetype`009maximum of 3 characters
X   version`009maximum of 5 digits
X
XIn most cases, filenames will fit in the above fields.  In the cases where a
Xfilename overflows one or more of the fields, an asterisk ('*') will appear
Xto the right of the filename to indicate that the full filename cannot be
Xdisplayed.  It is possible, however, to see the full filename by using the
XExpand command.
X
XThe protection string for a file is not enclosed in parentheses as it is
Xfor the DCL DIRECT command.  This is done to save space on the screen.
X
XWhen a file has one or more file commands associated with it, it will appear
Xin bold on the screen (for terminals that have this capability).
X
XThere is a limit on the number of characters that may be displayed for the
Xcurrent default directory at the top of the screen.  It depends on the mode
Xof the terminal at the time (80- or 132-column).  MAINT will truncate any
Xdefault directory string that is too long to fit.
X2 Single_file_commands
XThe following commands operate on the file pointed to by the cursor.  Re-
Xmember that none of the commands will be attempted until the X (eXecute)
Xcommand is issued.  The normal keyboard keys, as well as VT200 keys and
Xother alternatives keys, are listed for the commands.
X
X   Command          Keystroke         Description
X   -------          ---------         -----------
X   Acl              A or a            Edit the ACL for the file.  You will
X                                      be placed in the VAX/VMS ACL editor
X                                      and returned to MAINT when you exit.
X
X   Delete           D or d            Mark the file for deletion
X                    Remove
X
X   Rename           R or r            Rename the file.  You will be promp-
X                                      ted for the new file name.
X
X   Protect          P or p            Protect the file.  You will be promp-
X                                      ted for the new protection.  It should
X                                      be input in exactly the same format as
X                                      it would be at DCL.
X
X   Copy             C or c            Copy the file to another.  You will
X                                      be prompted for the new file name.
X
X   Unmark           U or u            Cancel all file commands for file.
X
X   Select           S or s            If the file is a subdirectory, tra-
X                                      verse into that directory (saving the
X                                      state of the current directory) and
X                                      begin working with that directory.
X                                      Otherwise, attempt to display the file
X                                      to the screen.
X
X   Expand           E or e            Expand on file; give information
X                                      similar to DIRECT/FULL, along with
X                                      any file commands associated with the
X                                      file.
X
X   Text             T or t            If the MAINT.TDF file already exists
X                                      for the current directory, create/
X                                      modify the text descriptor for the
X                                      file.  If no MAINT.TDF file exists,
X                                      ask if one should be created and
X                                      prompt for the text descriptor for
X                                      the directory itself.
X
X
X2 Screen_cursor_commands
XThe following commands are used for position the cursor on the screen
Xand for changing screens.  The normal keyboard keys, as well as VT200
Xkeys and other alternative keys, are listed for the commands.
X
X   Command          Keystroke         Description
X   -------          ---------         -----------
X   Next screen      +, =              Go to next screen in directory
X                    Next Screen
X                    Control-F
X
X   Previous screen  -, _              Go to previous screen in directory
X                    Prev Screen
X                    Control-B
X
X   Right-arrow      Right-arrow       Move cursor right one column
X                    Space
X                    Tab
X                    Greater than >
X                    Control-L
X
X   Left-arrow       Left-arrow        Move cursor left one column
X                    Less than <
X                    Control-H
X
X   Up-arrow         Up-arrow          Move cursor up one row
X                    Caret `094
X                    Control-K
X
X   Down-arrow       Down-arrow        Move cursor down one row
X                    Control-J
X
X   Goto screen      G or g            Go to a specific screen (useful for
X                                      multiple-screen directories).  This
X                                      option does not appear on the options
X                                      line because there is not enough room.
X2 General_commands
XThe following commands are used for general commands that not specific
Xto any one file.  The normal keyboard keys, as well as VT200 keys and
Xother alternatives keys, are listed for the commands.
X
X   Command          Keystroke         Description
X   -------          ---------         -----------
X   DCL escape       $                 Escape to DCL and execute a single
X                    !                 command.  You will be prompted for
X                                      the command to be executed.  If a
X                                      carriage-return is specified,
X                                      you will be returned to DCL level
X                                      exactly as if a `094Push command had
X                                      been entered.  After the specified
X                                      command is executed, MAINT will
X                                      ask for a carriage-return before
X                                      continuing.
X
X   Execute          X or x            Execute all file commands for the
X                    Do                current directory
X
X   Finish           F or f            Finished with current directory;
X                                      go back to most recent previous
X                                      directory without executing commands
X
X   Help             Help              Access HELP for MAINT.  You will be
X                    H or h            prompted for a topic for help.  If
X                                      no topic is given, HELP will be
X                                      entered at the beginning.
X
X   Locate           L or l            Search for a file in the current`032
X                    Find              directory.  Prefix searching is
X                                      done so only enough of the filename
X                                      to make it unique is necessary.  You
X                                      will be prompted for the search
X                                      string.
X
X   `094Push            Control-P         Temporarily suspend MAINT and go to
X                    Insert Here       DCL.  The DCL prompt will be "Maint> "
X                                      to indicate that you are running a
X                                      subprocess of MAINT.  This is diff-
X                                      erent from the DCL Escape command in
X                                      that Push means return to DCL while
X                                      DCL Escape command means execute a
X                                      single DCL command and return to
X                                      MAINT.
X
X   Quit             Q or q            Quit MAINT and return to DCL imme-
X                    Control-Z         diately
X
X   Refresh          Control-W         Refresh the screen.
X
X   Version          V or v            Display current version of MAINT
X2 Text_descriptors
XMAINT has the ability to maintain extended textual descriptors for files
Xwithin a given directory.  What text descriptors do is allow you to asso-
Xciate up to a 40-character description with any file in a directory, along
Xwith having up to a 60-character description of the directory itself.  This
Xis particularly useful when MAINTaining directories with a large number of
Xfiles.  To use the extended file descriptor facility, do the following:
X
X   1.  Run MAINT.
X
X   2.  Type a T (Text) command.
X
X   3.  MAINT will ask
X       Text descriptor file MAINT.TDF does not exist.  Create it [y]?
X
X   4.  Respond with something other than N or n for the file to be created.
X
X   5.  MAINT will then ask
X       Text descriptor for directory:
X
X   6.  Enter a text descriptor (up to 60 characters) for the DIRECTORY.
X       This will serve as a descriptor of the group of files in the
X       DIRECTORY and will appear at the top of the screen.
X
X   7.  MAINT will then ask
X       Commands will be wiped out.  eXecute them? [y]
X
X   8.  Enter something other than N or n to have the all of the current file
X       commands eXecuted when the text descriptor file MAINT.TDF is created.
X       If you answer n, MAINT will discard all of the file command made up
X       until this point.  The default is to execute the commands.
X
X   9.  MAINT will rebuild the directory information and rebuild the screen,
X       including the text descriptors for the directory and text descriptor
X       file itself, provided they will fit on the screen.  Even if they
X       can't fit on the screen, they are still available for each file via
X       the E (Expand) command.
X
XThe text descriptor file has now been created.  To add or modify a text
Xdescriptor for a file, move to a the file and type a T (Text) command.  You
Xwill be prompted for the text descriptor for the file.  It will be updated
Xwhen you Xecute the commands for the directory.
X
XOn subsequent uses of MAINT, text mode may be entered by one of two methods:
X
X   1.  Use the /TEXT qualifier on the MAINT command.  This will cause MAINT
X       to use text mode if the file MAINT.TDF exists.
X
X   2.  Use the T (Text) command.  Again, if MAINT.TDF exists, MAINT will
X       enter text mode.
X
XEither way, once in text mode, the T (Text) command may be used to add or
Xchange the text descriptor for a file.
X2 Other_features
XIf you are running MAINT and you receive new mail, you will be notified by
Xa message appearing in the bottom-right corner of your screen.  Similarly,
Xif you are being PHONEd, a message will appear in the bottom right corner
Xand MAINT will continue to beep as long as you are being PHONEd.  If you
Xwish to read your new mail or answer the phone, just push (see Push command
Xabove) out of MAINT and do so.
X2 Caveats      `032
XSome things to remember when running MAINT:
X
X   1) A file cannot be reprotected if you don't have WRITE access to it.
X
X   2) Protecting a file with a protection string of S:,O:,G:,W: (no access
X      for all four classes) will leave the protection unchanged.  Both
X      this and #1 will be fixed in the future; they require talking right
X      to the XQP, which is something I haven't figured out yet.
X       `032
X   3) Select will try to display any file, even if it is a .EXE, .OBJ, or
X      .MAI file.  MAINT might complain after it tries to display it, though.
X
X   4) You cannot move backwards through a file using Select.  Use the editor
X      if you want this functionality.
X
X   5) Files with escape sequences in them can be selected but the escape
X      sequences will not be interpreted.  The escape character will appear
X      as `094[.  The inability to interpret escape sequences is an SMG limi-
X      tation and one that probably cannot be fixed.
X
X   6) There is no way to edit a file from MAINT.  If you want to edit a
V      file, `094Push out of MAINT and edit it.  When you push out, you will b
Xe
X      in the same directory you were in while in MAINT.  Edit the file and
X      when you are finished, type "log" to return to MAINT.
X
X   7) Highly volatile directories might not always be up to date in MAINT.
X
X`009`009`009`009- Author
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAINT.NEWS"
$ CHECKSUM_IS = 83893593
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
XMAINTaining file systems and directories -- a new frontier
X----------------------------------------------------------
X
XMaintaining a large number of files/directories can be a tedious task when
Xall you have is DCL commands to work with.  Typing COPY, DELETE, TYPE,
XRENAME, and PROTECT gets a little time-consuming after a while.  You have
Xto do a few commands, often making typing mistakes in the process, and
Xthen do a DIRECT to see the current state of the files/directories.  Wouldn't
Xit be nice to have one program designed to combine all of this functionality
Xinto one nice package?
X
VMAINT is a program that does that and much more.  It combines the functionali
Xty
Xof all of the above DCL commands, adds some new functions, and packages all
Xof it with a full-screen interface that allows you to work with multiple
Xfiles/directories quickly, easily, and efficiently.
X
XThe following functions are available in MAINT:
X
X  1) delete files/directories
X  2) copy files
X  3) rename files/directories
X  4) protect files/directories
X  5) edit an Access Control List (ACL) for a file/directory
X  6) list a file's contents to the screen
V  7) change to a subdirectory and start over, saving the state of all command
Xs
X     in the current directory
X  8) get expanded information about a file
X  9) search for a specific file in a directory
X 10) suspend MAINT and return to DCL level
X 11) create extended textual descriptors for files and directories
X 12) access the help library for MAINT
X
XDirectories are presented to you in a series of one or more screens, allowing
Xyou to work with an entire directory all at once.  You can also select what
Xinformation should be included on the screen for each file by specifying
Xdifferent qualifiers when the program is invoked.  A few of the qualifiers
Xare:
X
X   /DATE`009include the creation date for all files
X   /SIZE`009include the file size of each file in number of blocks used
X   /PROTECTION`009include the protection string for the file
X   /FULL`009equivalent to /DATE/SIZE/PROTECTION
X
XAnother handy qualifer is /WIDE which will set your terminal to 132-column
Vmode if it can.  This means that more files can appear on each screen, allowi
Xng
Xyou to see more of a directory at one time.  For example, if you only wanted
Xthe filenames and you specify the /WIDE qualifer, you can have 114 files on
Xthe screen at one time!  Try doing that with the DCL DIRECT command.
X
XMAINT works within the directory structure provided by VMS, that of a tree.
XThis being the case, the first directory that the programs sees is considered
Vthe "root" of the session and is the highest-level directory that is accessib
Xle
Xfor the duration of the session.  Any descendant directories may be accessed,
Xwhich will be seen shortly.
X
XOne very important feature of MAINT is that execution of the operations on
Xthe files is NOT done until you tell it to go ahead and perform them.  In
Xother words, you can work with all of the files, specifying the operations,
Xand then tell MAINT to execute them all at once.  This means that you have
Xtime to change your mind and perhaps cancel the operations on one or more
Xof the files that will be acted upon.
X
XThe syntax to run MAINT is:
X
X   $ MAINT/qualifier(s) [directory-spec]
X
X   where
X
X`009[directory-spec]`009optional starting root directory and optional
X`009`009`009`009starting file specification; if not specified,
X`009`009`009`009the current default directory will be used
X`009`009`009`009and all files in the directory will be included.
X`009`009`009`009A file specification will only be in force for
X`009`009`009`009the first level of the session; if a sub-
X`009`009`009`009directory is selected, all files will be in-
X`009`009`009`009cluded.
X
X
XMoving around in MAINT
X----------------------
X
XOnce you are in MAINT, you move the cursor with the cursor keys (or one of
Xthe alternate keys defined to accomplish cursor movement) to the file that
Xwish to act upon.  You than select one of the single-keystroke commands and
Xyou are prompted for the information necessary.  This dramatically cuts down
Xon the typing.  To change screens (for directories that take up more than
Xone screen), you press one of the keys defines for Next Screen or Previous
XScreen.  The screen will be updated to reflect the new screen in the dir-
Xectory, saving any work done on previous screens.
X
XThe commands to position the cursor on the screen and for changing screens
Xare available via the MAINT/HELP Screen_cursor_commands.
X
X
XChanging directories/viewing files
X----------------------------------
X
XTo change to a subdirectory, you move the cursor to the directory you desire
Xand Select it.  You will be placed on the first screen of the subdirectory
Xand you can then work with the files in that directory.  Rest assured that
Xfile commands done in the "parent directory" will be preserved until you
Xreturn to that directory.  You can keep going down subdirectories, marking
Xfiles for action, and then execute them on your way back up.
X
XSingle file commands
X--------------------
X
XTo perform operations on a file, a single keystroke is needed.  The commands
X(and their associated keystrokes) will appear at the bottom of the screen,
Vthe first character of each command being the keystroke needed.  The exceptio
Xn
Vbeing the `094Push command, which actually needs a control-P to be invoked.
X  That
Xis what the "`094P" is supposed to signify.  Just move the cursor next to the
Xdesired file and invoke the command.  You will be prompted for any necessary
Xinformation.
X
XThe commands to perform single file commands are available via the MAINT/HELP
XSingle_file_commands command.
X
XText descriptors
X----------------
X
XMAINT has the ability to maintain extended textual descriptors for files
Xwithin a given directory.  What text descriptors do is allow you to asso-
Xciate up to a 40-character description with any file in a directory, along
Xwith having up to a 60-character description of the directory itself.  This
Xis particularly useful when MAINTaining directories with a large number of
Xfiles.  See the MAINT/HELP Text_descriptors command for more information.
X
XOther commands
X--------------
X
XMAINT provides other functions to make life easier on you.  For instance,
Vsuppose you want to go back to DCL temporarily.  The `094Push function (invok
Xed
Vby pressing control-P) will suspend MAINT and place you at DCL in the directo
Xry
Xthat you were in while in MAINT.  Your prompt will be Maint> to indicate that
Xyou are running a subprocess.  You now have all of DCL's functions available.
VTo return to MAINT, simply type "log" and you will pick up where you left off
X.
X
XTo execute the commands that you have made on files in a directory, press the
VX (eXecute) key.  The commands will be executed, informing you of their statu
Xs,
Vwhether it be success or failure.  After the commands are executed, the infor
X-
Xmation for the current directory is rebuilt and the screen will then reflect
Xthe new state of the files in the directory.
X
XTo search for a specific file in the current directory, the Locate command
Xis nice.  You will be prompted for a search string and if a file exists with
Xthe search string as a prefix, the cursor will be placed next to the file,
Xeven if it is on another screen in the directory.
X
XTo edit an Access Control List (ACL) for a file/directory, simply press the
XA (ACL) key.  You will be placed into the ACL editor for the selected file/
Xdirectory.
X
XOther features
X--------------
X
XIf you are running MAINT and you receive new mail, you will be notified by
Xa message appearing in the bottom-right corner of your screen.  Similarly,
Xif you are being PHONEd, a message will appear in the bottom right corner
Xand MAINT will continue to beep as long as you are being PHONEd.  If you
Vwish to read your new mail or answer the phone, just `094Push out of MAINT an
Xd
Xdo so.
X
XSummary
X-------
X
XMAINT attempts to provide you with a quick and elegant method for maintaining
Xfiles/directories but does not do eveything that you can do at DCL (at least
Vnot at the present time!).  It can be a useful tool, however, and any comment
Xs/
Xsuggestions/flames are greatly appreciated.  Send them to PEIRCE on VMS MAIL.
X
XThe full help for MAINT can be accessed via the VMS command MAINT/HELP or the
XH (Help) command when running MAINT.  Descriptions of all of the run-time
Xqualifiers and commands are available here, along with other information
Xabout running MAINT.
$ GOSUB UNPACK_FILE

$ FILE_IS = "MAINT2.C"
$ CHECKSUM_IS = 974200248
$ COPY SYS$INPUT VMS_SHARE_DUMMY.DUMMY
V/****************************************************************************
X**
V*****************************************************************************
X**
X
X   Installation:  Western Michigan University Academic Computer Center
X
X   System:`009Directory/File System Maintenance
X `032
X   Program:`009maint
X
X   Version=01`009Level=01`00908/24/87`009Leonard J. Peirce
X
X   Purpose:`009This file contains routines used in maint but could be
X`009`009conveniently placed in another source file.  These routines
X`009`009were moved here because the first source file was getting
X`009`009too big to deal with.
X
X   Version=01`009Level=02`00912/17/87`009Leonard J. Peirce
X
X   Purpose:`009Add a few new routines for some added functionality and fix
X`009`009a few bugs.  See maint.c for more information about this
X`009`009version.
X
X   Version=01`009Level=03`00908/04/88 `009Leonard J. Peirce
X
X   Purpose:`009See maint.c for more information about this version.
X
X   Version=01`009Level=04`00910/06/88 `009Leonard J. Peirce
X
X   Purpose:`009Actually, these fixes were made for Version 1.5.
X
X   Version=01`009Level=06`00906/06/89 `009Leonard J. Peirce
X
X   Purpose:`009Include all versions of a file instead of just the highest
X`009`009version in some situations.
X
X   Arguments:`009See individual functions.
X
X   External variables:  none
X
X   WMU external functions:
X
X          Defined:
X
X          Called:`009strindex,strins,cat,banystr
X
X   Files accessed:`009None.
X
X   Return codes:`009See individual functions.
X
X   Compiling instructions:  cc maint2.c/optimize
X
X   Linking instructions:  see linking instructions in maint.c
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*                        # I N C L U D E   F I L E S                    `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X#include "maint.h"`009`009`009/* our very own header file`009      */
X
X#ifdef WMUACC`009`009`009`009/* we have these in a .TLB`009      */
X
X#include utype`009`009`009`009/* unsigned data type header`009      */
X#include clidef`009`009`009`009/* for CLI$ stuff`009`009      */
-+-+-+-+-+ End of part 6 +-+-+-+-+-

