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

Received: From KL.SRI.COM by CRVAX.SRI.COM with TCP; Thu,  8 JUN 89 07:30:32 PDT
Received: from ucbvax.Berkeley.EDU by KL.SRI.COM with TCP; Thu, 8 Jun 89 07:31:21 PDT
Received: by ucbvax.Berkeley.EDU (5.61/1.36)
	id AA03006; Thu, 8 Jun 89 07:12:16 -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: 8 Jun 89 13:21:50 GMT
From: peirce@gumby.wisc.edu  (Leonard J. Peirce)
Organization: Western Michigan University, Kalamazoo, MI
Subject: MAINT -- Full Screen File/Directory Maintenance (Part 7 of 11)
Message-Id: <742@gumby.cc.wmich.edu>
Sender: info-vax-request@kl.sri.com
To: info-vax@kl.sri.com

+-+-+-+ Beginning of part 7 +-+-+-+
X#include itmlst`009`009`009`009/* for item list definition`009      */
X#include acldef`009`009`009`009/* some stuff for the ACL editor      */
X#include fscndef`009`009`009/* for SYS$FILESCAN stuff`009      */
X
X#else`009`009`009`009`009/* look in current directory...`009      */
X`009`009`009`009`009/* ...for everyone else`009`009      */
X#include "utype.h"
X#include "clidef.h"
X#include "itmlst.h"
X#include "acldef.h"`009`009`009`009
X#include "fscndef.h"
X#endif
X
X#include stdio`009`009`009`009/* standard I/O; for NULL definition  */
X#include rms`009`009`009`009/* RMS header; includes all others    */
X#include descrip`009`009`009/* for descriptors`009`009      */
X#include lnmdef`009`009`009`009/* logical name symbolic values`009      */
X#include ssdef`009`009`009`009/* SYS$ return code symbolics`009      */
X#include climsgdef`009`009`009/* for more CLI$ stuff`009`009      */
X#include smgdef`009`009`009`009/* for SMG$ symbolic definitions      */
X#include ctype`009`009`009`009/* character-type header`009      */
X#include string`009`009`009`009/* C string functions`009`009      */
X
V/****************************************************************************
X**/
V/*                                                                       `032
X    */
V/*                             # D E F I N E S                           `032
X    */
V/*                                                                       `032
X    */
V/****************************************************************************
X**/
X
X#define PROMPT_MAX 15`009`009`009/* max. length of prompt`009      */
X#define DEFAULT_FILESPEC "NONAME.TXT"
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
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
Vglobalvalue`009  LIB$K_CLI_GLOBAL_SYM,`009/* for LIB$GET_SYMBOL()'s sake`009
X      */
X`009`009  ACLEDIT$C_OBJNAM,`009/* stuff for the ACL editor`009      */
X`009`009  ACLEDIT$C_OBJTYP,
X`009`009  ACLEDIT$C_OPTIONS,
X`009`009  ACLEDIT$V_JOURNAL,
X`009`009  ACLEDIT$V_RECOVER,
X`009`009  ACLEDIT$V_KEEP_RECOVER,
X`009`009  ACLEDIT$V_KEEP_JOURNAL,
X`009`009  ACLEDIT$V_PROMPT_MODE,
X`009`009  ACLEDIT$C_BIT_TABLE;
X
Vextern`009 char`009  *strncat(),`009`009/* finite string concatenate`009 `032
X    */
X`009`009  *strchr(),`009`009/* find char in string`009`009      */
X`009`009  *strcpy(),`009`009/* string copy`009`009`009      */
X`009`009  *strcat();`009`009/* string concatenate`009`009      */
X
Xextern`009 ULONG`009  CLI$GET_VALUE(),
X`009`009  SYS$IDTOASC(),
X`009`009  LIB$FIND_FILE(),
X`009`009  LIB$FIND_FILE_END(),
X`009`009  LIB$FREE_VM(),
X`009`009  LIB$GET_VM(),
X`009`009  LIB$GET_SYMBOL(),
X`009`009  LIB$SPAWN(),
X`009`009  SMG$ERASE_DISPLAY(),
X`009`009  SMG$PASTE_VIRTUAL_DISPLAY(),
X`009`009  SMG$PUT_CHARS(),
X`009`009  SMG$READ_KEYSTROKE(),
X`009`009  SMG$READ_STRING(),
X`009`009  SMG$UNPASTE_VIRTUAL_DISPLAY(),
X`009`009  SYS$CLOSE(),
X`009`009  SYS$CONNECT(),
X`009`009  SYS$CREATE(),
X`009`009  SYS$CRELNM(),
X`009`009  SYS$ERASE(),
X`009`009  SYS$FILESCAN(),
X`009`009  SYS$OPEN(),
X                  SYS$PARSE(),
X`009`009  SYS$RENAME(),
X`009`009  SYS$SETDDIR();
X
Vextern`009 int`009  strins(),`009`009/* insert a string in another`009      *
X/
X`009`009  strindex(),`009`009/* search for substring of a string   */
X`009`009  banystr(),`009`009/* search for a character in a string */
X`009`009  sleep(),`009`009/* C version of LIB$WAIT()`009      */
X`009`009  delete();`009`009/* delete file`009`009`009      */
X
Xextern`009 void`009  LIB$STOP();
X
X`009 POOL_DEF *new_pool();`009`009/* initialize a new memory pool`009      */
X
X`009 char`009  *mystrcpy(),`009`009/* string copy returning pointer      */
X`009`009  *get_pool_mem(),`009/* get pointer to a memory slot`009      */
X`009`009  *nullptr = "";`009/* pointer to a null string`009      */
X
X`009 ULONG`009  push(),`009`009/* spawn a subprocess`009`009      */
X`009`009  get_string(),`009`009/* prompt and read string from tty    */
X`009`009  edit_acl();`009`009/* edit a file's ACL`009`009      */
X
X`009 short`009  get_num_file(),`009/* get number of files in a directory */
X`009`009  mark_delete(), `009/* set file to be deleted`009      */
X`009`009  mark_copy_ren(),`009/* set file to be copied/renamed      */
X`009`009  mark_protect(),`009/* set file to be reprotected`009      */
X`009`009  mark_text(),`009`009/* set file's text descriptor`009      */
X`009`009  make_slot(),`009`009/* create a screen slot for a file    */
X`009`009  create_text(),`009/* attempt to create text desc. file  */
X`009`009  expand(),`009`009/* get attributes of a file`009      */
X`009`009  get_scr_num(),`009/* let user specify new screen number */
X`009`009  put_line(),`009`009/* write a line to a virtual display  */
X`009`009  prot_val_to_str();`009/* get string value for protection    */
X
X`009 void`009  get_device(),`009`009/* get terminal name for debugging    */
X`009`009  info_mess(),`009`009/* write informational message`009      */
X`009`009  curr_dir(),`009`009/* get current directory spec`009      */
X`009`009  init_pool(),`009`009/* initialize memory pool nodes`009      */
X`009`009  reset_pool(),`009`009/* setup pools to reuse memory`009      */
X`009`009  put_pool(),`009`009/* copy a string to the memory pools  */
X`009`009  free_pool(),`009`009/* free memory pools for a directory  */
X`009`009  clear_mess(),`009`009/* clear a message from the screen    */
X`009`009  set_width(),`009`009/* set scr_width variable correctly   */
X`009`009  mark_cancel(),`009/* cancel commands for a file entry   */
X `009`009  set_direct(),`009`009/* change to command line directory   */
X`009`009  set_args(),`009`009/* set run-time args and other stuff  */
X`009`009  tag_file(),`009`009/* "tag" current file on screen`009      */
X`009`009  erase_tag(),`009`009/* erase file tag`009`009      */
X`009`009  set_sysdisk(),`009/* set SYS$DISK logical`009`009      */
X`009`009  put_text(),`009`009/* put directory text descrip on scr. */
X`009`009  xecute(),`009`009/* execute file commands`009      */
X`009`009  free_com(),`009`009/* free command structures`009      */
X`009`009  exp_prot_str(),`009/* make VMS-style protection string   */
X`009`009  xmess();`009`009/* display messages while executing   */
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
Vstatic`009 COM_DEF  *new_comm();`009`009/* allocate command structure`009`032
X     */
X
Vstatic`009 ULONG`009  write_text();`009`009/* write text descriptor record`00
X9      */
X
Vstatic`009 short`009  put_buf(),`009`009/* write a buffer to a virtual disp
X   */
X`009`009  put_line(),`009`009/* write a line to a virtual display  */
X`009 `009  prot_str_to_val(),`009/* compute protection integer value   */
X`009`009  put_acl(),`009`009/* display ACL's on eXpand`009      */
X`009`009  banynstr(),`009`009/* search finite-length string`009      */
X`009`009  make_name();`009`009/* create filename for file operation */
X
Vstatic`009 void`009  free_comstr(),`009/* free up a specific command struct
X  */
X`009`009  parse_arg(),`009`009/* parse the command line file spec   */
X`009`009  copy_spec(),`009`009/* copy directory, device, file specs */
X`009`009  make_text_rec();`009/* make text descriptor record`009      */
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009get_device
X
X  Purpose:`009This routine is used only for debugging purposes.  It obtains
X`009`009the name of the device to be used when debugging from the
X`009`009global symbol MAINT_DEV and uses it when creating the paste-
X`009`009board for the session.
X
X  Global variables:
X                     `032
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
Xvoid get_device(outdev_d,indev_d)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Vstruct`009 dsc$descriptor_s  *outdev_d,`009/* destination for device name`009
X      */
X`009`009`009   *indev_d;`009/* for creating virtual keyboard      */
X
X`123`009/*** get_device ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status`009`009      */
X`009 short`009  length;`009`009/* length of symbol value returned    */
Vstatic $DESCRIPTOR(sym_d,"MAINT_DEV");`009/* symbol to look for`009`009  `032
X   */
X
X                                `032
X#ifdef DEBUG
X
X   status = LIB$GET_SYMBOL(&sym_d,outdev_d,&length,&LIB$K_CLI_GLOBAL_SYM);
X
X   if(status != SS$_NORMAL)
X      LIB$STOP(status);
X
X   /* terminate the symbol value in the return descriptor */
X
X   outdev_d->dsc$a_pointer[length] = '\0';
X   indev_d->dsc$w_length = length;
X   strcpy(indev_d->dsc$a_pointer,outdev_d->dsc$a_pointer);
X
X#else
X
X   /* just set up the normal stuff for using the correct terminal */
X
X   strcpy(indev_d->dsc$a_pointer,"SYS$INPUT");
X   strcpy(outdev_d->dsc$a_pointer,"SYS$OUTPUT");
X   indev_d->dsc$w_length = strlen(indev_d->dsc$a_pointer);
X   outdev_d->dsc$w_length = strlen(outdev_d->dsc$a_pointer);
X
X#endif
X
X   return;
X
X`125`009/*** get_device ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009curr_dir
X
X  Purpose:`009Obtain the current default directory specification.
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
Xvoid curr_dir(dir_name)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *dir_name;`009`009/* where to write directory spec      */
X
X`123`009/*** curr_dir ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status`009`009      */
X`009 char`009  *tptr;`009`009/* temporary character pointer`009      */
Vstatic`009 short`009  pass;`009`009`009/* have we been here before?`009  `032
X   */
Vstatic`009 struct`009  FAB`009  fab;`009`009/* file access block`009`009 `032
X    */
Vstatic`009 struct`009  NAM`009  nam;`009`009/* name access block`009`009 `032
X    */
X
X
X   if(!pass)`009`009`009`009/* have we already initialized stuff? */
X   `123
X      fab = cc$rms_fab;`009`009`009/* no, initialize the RMS blocks      */
X      nam = cc$rms_nam;
X
X      fab.fab$l_dna = "[]";`009`009/* set up for getting default dir     */
X      fab.fab$b_dns = 2;
X      fab.fab$l_fna = "[]";
X      fab.fab$b_fns = 2;
X      fab.fab$l_fop = FAB$M_OFP `124 FAB$M_NAM;
X      fab.fab$l_nam = &nam;`009`009/* set up NAM block address`009      */
X
X      nam.nam$b_nop = NAM$M_PWD `124 NAM$M_SYNCHK;
X      nam.nam$b_ess = NAM$C_MAXRSS;
X      pass = 1;`009`009`009`009/* make sure we do this only once.... */
X   `125
X
X   nam.nam$l_esa = dir_name;`009`009/* where do we want it to go?`009      */
X
X   status = SYS$PARSE(&fab,0,0);`009/* parse things....`009`009      */
X
X   if(status != RMS$_NORMAL)
X      LIB$STOP(status);`009`009`009/* #$*!@+?&`094`009`009`009      */
X
V   tptr = strchr(dir_name,']');`009`009/* find where directory spec ends `032
X   */
X   *(tptr + 1) = '\0';`009`009`009/* terminate it`009`009`009      */
X
X   return;`009`009`009`009/* go home`009`009`009      */
X
X`125`009/*** curr_dir ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009get_num_file
X
X  Purpose:`009Get the number of files in the current directory.  The formal
X`009`009parameter file_spec contains the string that is used to count
X`009`009the number of files in the current directory that will be
X`009`009included.
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`009count`009`009`009number of files in directory
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009return code from LIB$FIND_FILE()
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xshort get_num_file(file_spec)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *file_spec;`009`009/* file spec for current directory    */
X
X`123`009/*** get_num_file ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister ULONG`009  status;`009`009/* return code status`009`009      */
Xregister short`009  count;`009`009/* number of files in directory`009      */
Vstatic`009 ULONG`009  fcontext;`009`009/* file context for getting files `032
X   */
Vstatic`009 char`009  buf2[BUFSIZ];`009`009/* resulting filename`009`009  `032
X   */
Vstatic $DESCRIPTOR(file_d,"");`009`009/* descriptor for wildcard string     *
X/
Xstatic $DESCRIPTOR(file2_d,buf2);`009/* resultant file-spec descriptor     */
X
X
X   file_d.dsc$a_pointer = file_spec;
X   file_d.dsc$w_length = (USHORT) strlen(file_spec);
X
X   fcontext = 0L;`009`009`009/* initialize context`009`009      */
X   count = 0;`009`009`009`009/* MUST initialize register variable! */
X
X   /* now parse the wildcard file specification, counting each file as
X    * we go along
X    */
X
X   status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext);
X
X   while(status == RMS$_NORMAL)
X   `123
X      count++;`009`009`009`009/* count it`009`009`009      */
X      status = LIB$FIND_FILE(&file_d,&file2_d,&fcontext);
X   `125
X
X   if(!count) `009`009`009`009/* did we find any files?`009      */
X      return(0);`009`009`009/* in case directory is empty...      */
X
X   if(status != RMS$_NMF)`009`009/* did we stop for the right reason?  */
X      LIB$STOP(status);`009`009`009/* nope.....`009`009`009      */
X
X
X   /* terminate the "finding" of files */
X
X   status = LIB$FIND_FILE_END(&fcontext);
X
X   if((status != SS$_NORMAL) && (status != RMS$_NORMAL))
X      LIB$STOP(status);
X
X   return(count);`009`009`009/* return number of files`009      */
X
X`125`009/*** get_num_file ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009set_sysdisk
X
X  Purpose:`009Set the value of the SYS$DISK logical to the specified value.
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
Xvoid set_sysdisk(dev_spec)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *dev_spec;`009`009/* value to set SYS$DISK to`009      */
X
X`123`009/*** set_sysdisk ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
Vstatic $DESCRIPTOR(table_d,"LNM$PROCESS"); /* where SYS$DISK is`009`009  `032
X   */
Vstatic $DESCRIPTOR(logical_d,"SYS$DISK"); /* this is what we need to set `032
X    */
Vstatic`009 ITM_LST  items[] = `123`009`009/* item list for SYS$CRELNM`009`032
X     */
X`1230,LNM$_STRING,NULL,NULL`125,
X`1230,0,NULL,NULL`125`125;
X
X
X   items[0].buf_len = (USHORT) strlen(dev_spec);
X   items[0].buf_addr = dev_spec;
X
X   status = SYS$CRELNM(0,&table_d,&logical_d,0,items);
X
X   if(status != SS$_NORMAL && status != SS$_SUPERSEDE)
X   `123
X      LIB$STOP(status);
X   `125
X
X   return;
X
X`125`009/*** set_sysdisk ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009set_direct
X
X  Purpose:`009Determine if a directory and/or file specification was speci-
X`009`009fied on the command line.  Change to the directory if appro-
X`009`009priate and save the filespec for parsing later if one was
X`009`009specified.
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
Xvoid set_direct(file_spec,dir_spec,dev_spec,user_dir)
X`009`009`009               `009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *file_spec,`009`009/* starting file specification        */
X`009`009  *dir_spec,   `009`009/* name of directory to start in      */
X`009`009  *dev_spec,   `009`009/* device specification               */
X`009`009  *user_dir;   `009`009/* user's directory at run-time       */
X
X`123`009/*** set_direct ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 char`009  *tptr,`009`009/* temporary character pointer`009      */
X`009`009  *tptr2;`009`009/* ditto.....`009`009`009      */
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 USHORT`009  leng;`009`009`009/* length of first parameter returned */
Vstatic`009 char`009  buf[NAM$C_MAXRSS+1];`009/* for holding the first paramet
Xer    */
Vstatic $DESCRIPTOR(file_d,"INFILE");`009/* for getting the first parameter
X    */
Xstatic $DESCRIPTOR(buf_d,buf);`009`009/* output descriptor`009`009      */
Xstatic $DESCRIPTOR(dir_d,"");`009`009/* descriptor for changing directory  */
X
X
X   /* get the user's directory so that we can go back to it later */
X
X   curr_dir(buf);
X   tptr = strchr(buf,'[');`009`009/* get start of directory`009      */
X   tptr2 = strchr(tptr,']');`009`009/* get end of directory`009`009      */
X   strmcpy(user_dir,tptr,tptr2 - tptr + 1);
X
V   /* see if the user specified a directory specification on the command line
X */
X
X   status = CLI$GET_VALUE(&file_d,&buf_d,&leng);
X
X   if(status != CLI$_ABSENT)
X   `123  `032
X      /* now try to change to the directory that was left over after lopping
X       * off the filename or type
X       */
X
X      buf[leng] = '\0';`009`009`009/* make it a string`009`009      */
X
X      parse_arg(buf,file_spec,dir_spec,dev_spec);
X
X      if(*dev_spec != '\0')
X      `123
X`009 /* there is a device specification; we must set the SYS$DISK logical
X`009  * so that when we change directories, the device is correct; un-
X`009  * fortunately, SYS$SETDDIR can't handle directories that are on
X`009  * another device :-(
X`009  */
X
X`009 set_sysdisk(dev_spec);
X      `125
X
X      if(strcmp(dir_spec,"[]") != 0 && *dir_spec != '\0')
X      `123
X`009 /* only change directory if we need to */
X
X`009 dir_d.dsc$w_length = (USHORT) strlen(dir_spec);
X`009 dir_d.dsc$a_pointer = dir_spec;
X
X`009 status = SYS$SETDDIR(&dir_d,0,0);
X
X`009 if(status != RMS$_NORMAL)
X`009 `123
X`009    fprintf(stdout,
X`009`009    "\nMAINT:  Cannot change to specified directory\n\n");
X`009    exit();
X`009 `125
X      `125
X   `125
X   else
X   `123
X      strcpy(dir_spec,user_dir);`009/* just the current directory`009      */
X      strcpy(file_spec,"*.*;*");`009/* wildcard to get all files`009      */
X   `125
X
X   return;
X
X`125`009/*** set_direct ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009parse_arg
X
X  Purpose:`009Parse the command line argument into pieces that we can
X`009`009deal with.
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
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009return code from SYS$TRNLNM()
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void parse_arg(cmd_arg,file_spec,dir_spec,dev_spec)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *cmd_arg,`009`009/* command-line argument`009      */
X`009`009  *file_spec,`009`009/* file specification to return`009      */
X`009`009  *dir_spec,`009`009/* directory specification to return  */
X`009`009  *dev_spec;`009`009/* device specification to return     */
X
X`123`009/*** parse_arg ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
V       `009 ULONG`009  status,`009`009/* return code status holder`009      *
X/
X`009`009  status2;`009`009/* secondary return code status`009      */
X`009 USHORT`009  done,`009`009`009/* loop control flag`009`009      */
X`009`009  file_saved = 0,`009/* set if file name on command line   */
X`009`009  type_saved = 0,`009/* set if file type on command line   */
X`009`009  dir_saved = 0,`009/* set if directory spec saved`009      */
X`009`009  dev_saved = 0,`009/* set if device spec saved`009      */
X`009`009  ver_saved = 0;`009/* set if version saved`009`009      */
Xstatic`009 ULONG`009  attr;`009`009`009/* logical name attributes`009      */
Xstatic`009 short`009  length,`009`009/* length returned from SYS$TRNLNM()  */
X`009     `009  length2;`009`009/* length of attributes returned      */
Vstatic`009 char`009  buffer[BUFSIZ];`009/* buffer for holding translations
X    */
Xstatic $DESCRIPTOR(arg_d,"");`009`009/* descriptor for command-line arg    */
Xstatic $DESCRIPTOR(table_d,"LNM$PROCESS");
Xstatic $DESCRIPTOR(table2_d,"LNM$JOB");
Xstatic $DESCRIPTOR(table3_d,"LNM$GROUP");
Xstatic $DESCRIPTOR(table4_d,"LNM$SYSTEM");
Xstatic $DESCRIPTOR(logical_d,"");
Vstatic`009 struct`009  fscndef  items[] = `123`009/* for parsing file specifi
Xcations    */
X`1230,FSCN$_DEVICE,0L`125,
X`1230,FSCN$_DIRECTORY,0L`125,
X`1230,FSCN$_NAME,0L`125,
X`1230,FSCN$_TYPE,0L`125,
X`1230,FSCN$_VERSION,0L`125,
X`1230,0,0L`125`125;
Vstatic`009 ITM_LST  items2[] = `123`009`009/* item list for translating logic
Xals */
X`123sizeof(buffer),LNM$_STRING,buffer,&length`125,
X`123sizeof(attr),LNM$_ATTRIBUTES,&attr,&length2`125,
X`1230,0,NULL,NULL`125`125;
X
X
X   /* first parse the argument into 1) the device, 2) the directory, and
X    * 3) the filename
X    */
X
X   *file_spec = '\0';
X   arg_d.dsc$a_pointer = cmd_arg;
X   arg_d.dsc$w_length = (USHORT) strlen(cmd_arg);
X
X   status = SYS$FILESCAN(&arg_d,items,0);
X
X   if(status != SS$_NORMAL)
X   `123
X      printf("\nMAINT:  invalid command line argument\n");
X      SYS$EXIT();
X   `125  `032
X
X   /* right here, if we have a filename and spec, save them and clear them
X    * out of the item list
X    */
X
X   if(items[2].fscn$w_length && (items[0].fscn$w_length `124`124
X      items[1].fscn$w_length `124`124 items[3].fscn$w_length `124`124
X      banynstr(items[2].fscn$l_addr,"*%",items[2].fscn$w_length) != -1))
X   `123
X      strmcpy(file_spec,items[2].fscn$l_addr,items[2].fscn$w_length);
X      items[2].fscn$w_length = 0;
X      items[2].fscn$l_addr = NULL;
X      file_saved = 1;`009`009`009/* means we saved file name already   */
X   `125
X
X   if(items[3].fscn$w_length)
X   `123
X      strncat(file_spec,items[3].fscn$l_addr,items[3].fscn$w_length);
X      items[3].fscn$w_length = 0;
X      items[3].fscn$l_addr = NULL;
X      type_saved = 1;`009`009`009/* means we saved file type already   */
X   `125
X
X   if(items[4].fscn$w_length)
X   `123
X      strncat(file_spec,items[4].fscn$l_addr,items[4].fscn$w_length);
X      items[4].fscn$w_length = 0;
X      items[4].fscn$l_addr = NULL;
X      ver_saved = 1;  `009`009`009/* means we saved file type already   */
X   `125
X
X   if(items[1].fscn$w_length)
X   `123
X      /* save a directory spec if there is one */
X
X      strmcpy(dir_spec,items[1].fscn$l_addr,items[1].fscn$w_length);
X      dir_saved = 1;
X   `125
X
X   if(items[0].fscn$w_length)
X   `123
X      /* save the device spec if there is one */
X
X      strmcpy(dev_spec,items[0].fscn$l_addr,items[0].fscn$w_length);
X      dev_saved = 1;
X   `125
X
X   if(!items[1].fscn$w_length)
X   `123
X      /* hmmm....this might be a logical name so we must translate it until
X       * we get a directory spec; first set up the descriptor that points to
X       * what we want to translate
X       */
X
X      if(!items[0].fscn$w_length)
X      `123
X`009 logical_d.dsc$a_pointer = items[2].fscn$l_addr;
X`009 logical_d.dsc$w_length = items[2].fscn$w_length;
X      `125
X      else
X      `123
X`009 logical_d.dsc$a_pointer = items[0].fscn$l_addr;
X       `009 logical_d.dsc$w_length = items[0].fscn$w_length - 1;
X      `125
X
X      /* try to translate it */
X
X      length = 0;
X      done = FALSE;
X      arg_d.dsc$a_pointer = buffer;
X
X      status = SYS$TRNLNM(0,&table_d,&logical_d,0,items2);
X
X      while(status == SS$_NORMAL && !done)
X      `123
X`009 /* scan the resultant translation for a file specification; if
X`009  * we have one, we stop here and take it
X`009  */
X
X`009 arg_d.dsc$w_length = length;
X
X`009 status2 = SYS$FILESCAN(&arg_d,items,0);
X
X`009 if(status2 != SS$_NORMAL)
X`009    LIB$STOP(status2);
X
X`009 /* look to see if we have a file specification here; if not,
X`009  * translate it again
X`009  */
X
X`009 if(items[0].fscn$w_length == 0 && items[1].fscn$w_length == 0)
X`009 `123
X`009    /* no device or directory spec yet */
X
X`009    logical_d.dsc$a_pointer = buffer;
X`009    logical_d.dsc$w_length = (USHORT) length;
X
X`009    status = SYS$TRNLNM(0,&table_d,&logical_d,0,items2);
X`009 `125
X`009 else
X`009    done = TRUE;`009`009/* found one; exit loop....`009      */
X      `125
X   `125
X
X   /* if we have a filetype OR a device, we are finished since there is
X    * nothing left to translate; otherwise, 1) save the filename and
X    * file type if they BOTH exist; if one of them doesn't exist yet, defer
X    * saving them for the moment; 2) try to translate the device name until
X    * we get what we need
X    */
X
X   if(items[1].fscn$w_length `124`124 done)
X   `123
X      copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved,
X`009`009ver_saved);
X      return;
X   `125
X   else
X   `123
X      /* now the hard part; there is a device spec but no file name/type; we
X       * must try to translate the device spec until 1) we get both a device
X       * spec and a directory, or 2) we can't translate it anymore; we might
X       * have to move to another table to get the translation; we start
X       * with LNM$PROCESS
X       */
X
X      if(items[0].fscn$w_length)
X      `123
X`009 strmcpy(buffer,items[0].fscn$l_addr,items[0].fscn$w_length);
X`009 logical_d.dsc$w_length = items[0].fscn$w_length - 1;
X      `125
X      else
X      `123
X`009 strmcpy(buffer,items[2].fscn$l_addr,items[2].fscn$w_length);
X`009 logical_d.dsc$w_length = items[2].fscn$w_length;
X      `125
X
X      /* now try to translate it */
X
X      logical_d.dsc$a_pointer = buffer;
X      arg_d.dsc$a_pointer = buffer;
X      done = FALSE;
X
X      status = SYS$TRNLNM(0,&table_d,&logical_d,0,items2);
X
X      while(status == SS$_NORMAL && !done)
X      `123
X`009 /* scan it for device and directory spec */
X
X`009 arg_d.dsc$w_length = length;
X
X`009 status2 = SYS$FILESCAN(&arg_d,items,0);
X
X`009 if(status2 != SS$_NORMAL)
X`009    LIB$STOP(status2);
X
X`009 /* now see if we have a device and directory spec */
X
X`009 if(items[0].fscn$w_length == 0 && items[1].fscn$w_length == 0 &&
X`009   !(attr & LNM$M_TERMINAL))
X`009 `123
X`009    /* no device or directory spec yet */
X
X`009    logical_d.dsc$w_length = (USHORT) length;
X
X`009    status = SYS$TRNLNM(0,&table_d,&logical_d,0,items2);
X`009 `125
X`009 else
X`009    done = TRUE;`009`009/* found one; exit loop....`009      */
X      `125
X
X      /* why did we exit the loop?  if we have a directory and device spec,
X       * we're finished; if not, or the logical was terminal, we have to
X       * go to the next table and continue to try to translate
X       */
X
V      if(done `124`124 (items[0].fscn$w_length `124`124 items[1].fscn$w_lengt
Xh))
X      `123
X`009 copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved);
X`009 return;
X      `125
X
X      done = FALSE;
X
X      status = SYS$TRNLNM(0,&table2_d,&logical_d,0,items2);
X
X      while(status == SS$_NORMAL && !done)
X      `123
X`009 /* scan it for device and directory spec */
X
X`009 arg_d.dsc$w_length = length;
X
X`009 status2 = SYS$FILESCAN(&arg_d,items,0);
X
X`009 if(status2 != SS$_NORMAL)
X`009    LIB$STOP(status2);
X
X`009 /* now see if we have a device and directory spec */
X
X`009 if(items[0].fscn$w_length == 0 && items[1].fscn$w_length == 0 &&
X`009   !(attr & LNM$M_TERMINAL))
X`009 `123
X`009    /* no device or directory spec yet */
X
X`009    logical_d.dsc$w_length = (USHORT) length;
X
X`009    status = SYS$TRNLNM(0,&table2_d,&logical_d,0,items2);
X`009 `125
X`009 else
X`009    done = TRUE;`009`009/* found one; exit loop....`009      */
X      `125
X
V      if(done `124`124 (items[0].fscn$w_length `124`124 items[1].fscn$w_lengt
Xh))
X      `123
X`009 copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved);
X`009 return;
X      `125
X
X      done = FALSE;
X
X      status = SYS$TRNLNM(0,&table3_d,&logical_d,0,items2);
X
X      while(status == SS$_NORMAL && !done)
X      `123
X`009 /* scan it for device and directory spec */
X
X`009 arg_d.dsc$w_length = length;
X
X`009 status2 = SYS$FILESCAN(&arg_d,items,0);
X
X`009 if(status2 != SS$_NORMAL)
X`009    LIB$STOP(status2);
X
X`009 /* now see if we have a device and directory spec */
X
X`009 if(items[0].fscn$w_length == 0 && items[1].fscn$w_length == 0 &&
X`009   !(attr & LNM$M_TERMINAL))
X`009 `123
X`009    /* no device or directory spec yet */
X
X`009    logical_d.dsc$w_length = (USHORT) length;
X
X`009    status = SYS$TRNLNM(0,&table3_d,&logical_d,0,items2);
X`009 `125
X`009 else
X`009    done = TRUE;`009`009/* found one; exit loop....`009      */
X      `125
X
V      if(done `124`124 (items[0].fscn$w_length `124`124 items[1].fscn$w_lengt
Xh))
X      `123
X`009 copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved);
X`009 return;
X      `125
X
X      done = FALSE;
X
X      status = SYS$TRNLNM(0,&table4_d,&logical_d,0,items2);
X
X      while(status == SS$_NORMAL && !done)
X      `123
X`009 /* scan it for device and directory spec */
X
X`009 arg_d.dsc$w_length = length;
X
X`009 status2 = SYS$FILESCAN(&arg_d,items,0);
X
X`009 if(status2 != SS$_NORMAL)
X`009    LIB$STOP(status2);
X
X`009 /* now see if we have a device and directory spec */
X
X`009 if(items[0].fscn$w_length == 0 && items[1].fscn$w_length == 0 &&
X`009   !(attr & LNM$M_TERMINAL))
X`009 `123
X`009    /* no device or directory spec yet */
X
X`009    logical_d.dsc$w_length = (USHORT) length;
X
X`009    status = SYS$TRNLNM(0,&table4_d,&logical_d,0,items2);
X`009 `125
X`009 else
X`009    done = TRUE;`009`009/* found one; exit loop....`009      */
X      `125
X            `032
V      if(done `124`124 (items[0].fscn$w_length `124`124 items[1].fscn$w_lengt
Xh))
X      `123
X`009 copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved,
X`009`009   ver_saved);
X`009 return;
X      `125
X   `125
X
X   /* copy the file, directory, and device specifications to where they
X    * belong and apply any defaults that should be applied
X    */
X
V   copy_spec(dev_spec,dir_spec,file_spec,items,file_saved,type_saved,ver_save
Xd);
X
X   return;
X
X`125     `009/*** parse_arg ***/  `032
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009copy_spec
X
X  Purpose:`009Copy the file, directory, and device specifications to their
X`009`009resting places from the item list returned by SYS$FILESCAN,
X`009`009applying default values where appropriate.
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
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009return code from SYS$TRNLNM()
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xstatic void copy_spec(device,directory,filename,items,file_saved,type_saved,
X`009`009      ver_saved)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *device,`009`009/* device specification`009`009      */
X`009`009  *directory,`009`009/* directory specification`009      */
X`009`009  *filename;`009`009/* file name specification`009      */
Xstruct`009 fscndef  items[];`009`009/* item list from SYS$FILESCAN()      */
V`009 USHORT`009  file_saved,`009`009/* if set, don't need file name`009  `032
X   */
X`009`009  type_saved,`009`009/* if set, don't need file type`009      */
X`009`009  ver_saved;`009`009/* if set, don't neet version`009      */
X
X`123`009/*** copy_spec ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
V`009 char`009  *tptr = NULL,`009`009/* temporary character pointer`009      *
X/
X`009`009  *tptr2 = NULL;`009/* ditto.......`009`009`009      */
X
X
X   if(!file_saved)
X   `123
X      /* the filename has not been saved yet; now see if the file type has
X       * been saved yet; if it hasn't, then we just copy the filename to the
X       * appropriate place; otherwise, we have to insert it instead of just
X       * copying it because we don't want to trash the file type that is
X       * already there
X       */
X
X      if(!type_saved)
X      `123
X`009 if(items[2].fscn$w_length)
X`009    strmcpy(filename,items[2].fscn$l_addr,items[2].fscn$w_length);
X`009 else
X`009    strcpy(filename,"*");
X      `125
X      else
X      `123
X`009 if(items[2].fscn$w_length)
X`009 `123
X`009    /* what a pain */
X
X`009    tptr = (char *) items[2].fscn$l_addr;
X`009    tptr[items[2].fscn$w_length] = '\0';`009   `032
X`009    strins(filename,items[2].fscn$l_addr,0);
X`009    tptr[items[2].fscn$w_length] = '.';`009   `032
X`009 `125
X`009 else
X`009    strins(filename,"*",0);
X      `125
X   `125
X
X   if(!type_saved)
X   `123
X      /* we didn't get a file type from the command line; save whatever is
X       * appropriate here
X       */
X
X      if(items[3].fscn$w_length)
X`009 strncat(filename,items[3].fscn$l_addr,items[3].fscn$w_length);
X      else
X`009 strcat(filename,".*");
X   `125
X
X   if(!ver_saved)
X   `123
X      /* we didn't get a file type from the command line; save whatever is
X       * appropriate here
X       */
X
X      if(items[4].fscn$w_length)
X`009 strncat(filename,items[4].fscn$l_addr,items[4].fscn$w_length);
X      else
X`009 strcat(filename,";*");
X   `125
X
X   if(items[0].fscn$w_length)
X      strmcpy(device,items[0].fscn$l_addr,items[0].fscn$w_length);
X   else
X      *device = '\0';
X
X   /* save the directory spec */
X
X   if(items[1].fscn$w_length)
X      strmcpy(directory,items[1].fscn$l_addr,items[1].fscn$w_length);
X   else
X   `123
X      /* this is weird.....for some reason, SYS$FILESCAN will not detect a
X       * directory spec for something like _$255$DUA1:[SCR.]; it seems that
V       * this only happen with logicals names that translate to something wit
Xh
X       * a period adjacent to the right bracket; so......................
X       * if we find a directory like this, we will strip out the period
V       * because it will just mess us up later when we try to do a SYS$SETDDI
XR
X       * if we don't
X       */
X
X      if(items[0].fscn$l_addr)
X      `123
X`009 tptr = strchr(items[0].fscn$l_addr,'[');
X`009 tptr2 = strchr(items[0].fscn$l_addr,']');
X      `125
X
X      if(tptr && tptr2)
X      `123
X`009 /* look at character preceding the ']'; if its a period, get
X`009  * rid of it
X`009  */
X
X`009 if(*(tptr2 - 1) == '.')`009/* [xxx.] format?`009`009      */
X`009 `123
X`009    tptr2--;`009`009`009/* take out the period here...`009      */
X`009    *tptr2 = ']';
X`009 `125
X
X`009 strmcpy(directory,tptr,tptr2 - tptr + 1);
X      `125
X      else
X      `123
X`009 strmcpy(directory,"[]");
X      `125
X   `125
X
X   return;
X
X`125`009/*** copy_spec ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009push
X
X  Purpose:`009Spawn a subprocess that allows the user to escape to DCL.
X`009`009The call to LIB$SPAWN will hibernate the main process until
X`009`009the subprocess completes.  The subprocess will inherit all
X`009`009of the attributes of the user's login process.
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`009SS$_NORMAL`009`009everything ok
X`009SS$_NORMAL+1`009`009LIB$SPAWN() failed; couldn't push out
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
XULONG push(command)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 char`009  *command;`009`009/* command to be executed`009      */
X
X`123`009/*** push ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status,`009`009/* return code status`009`009      */
X`009`009  comp_status;`009`009/* subprocess completion status`009      */
Vstatic $DESCRIPTOR(prompt_d,"Maint> ");`009/* prompt for subprocess`009  `032
X   */
Xstatic $DESCRIPTOR(command_d,"");`009/* for forming the command`009      */
X
X
X
V   /* spawn the subprocess; LIB$SPAWN will put us to sleep and wake us up whe
Xn
X    * the subprocess completes; after we wake up, just return the completion
X    * code of the subprocess
X    */
X
V   command_d.dsc$a_pointer = command;`009/* set up the command descriptor`032
X     */
X   command_d.dsc$w_length = (USHORT) strlen(command);
X
X   status = LIB$SPAWN(&command_d,0,0,0,0,0,&comp_status,0,0,0,&prompt_d,0);
X
X   if(status != SS$_NORMAL)
X   `123
X      return(SS$_NORMAL+1);`009`009/* return something other than NORMAL */
X   `125
X
X   return(SS$_NORMAL);`009`009`009/* say that everything went ok`009      */
X
X`125`009/*** push ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009mystrcpy
X
X  Purpose:`009Version of strcpy that copies a string and returns a pointer
X`009`009to the null character in the destination string.
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`009dest - 1`009`009pointer to null character terminating the
X`009`009`009`009destionation string
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xchar *mystrcpy(dest,source)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister char`009  *dest,`009`009/* destination string`009`009      */
X`009`009  *source;`009`009/* source string`009`009      */
X
X`123`009/*** mystrcpy ***/
X
X   while(*dest++ = *source++)`009`009/* copy the source string to the dest */
X      ;
X
X   return(dest - 1);`009`009`009/* return pointer to null character   */
X
X`125`009/*** mystrcpy ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009mark_delete
X
X  Purpose:`009The selected file is to be deleted; allocate memory for the
X`009`009command structure (if necessary), link it to the entry, and
X`009`009set up the command structure so that the file can be deleted.
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`009completed successfully
X`009 -1`009`009`009problems allocating memory
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009LIB$FREE_VM() failed
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xshort mark_delete(ent)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Vregister ENT_DEF  *ent;`009`009`009/* entry for file to be deleted`009      *
X/
X
X`123`009/*** mark_delete ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister COM_DEF  *tptr;`009`009/* temporary command structure ptr    */
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 long`009  str_size;`009`009/* amount of memory to allocate`009      */
X
X
X   /* do we need a command structure or does the file already have one? */
X
X   if(ent->command == NULL)
X   `123
V      /* we need command structure; allocate it and link it to the file entry
X */
X
X      tptr = new_comm();
X      if(tptr == NULL)
X`009 return(-1);`009`009`009/* problems allocating memory`009      */
X
X      ent->command = tptr;`009`009/* link it to the file entry`009      */
X   `125
X   else
X   `123
X      tptr = ent->command;`009`009/* else use the one already there     */
X   `125
X
X   tptr->comm_del = 1;
X
X   /* deallocate all of the memory that might have been used for things
X    * like renaming the file and for a text descriptor
X    */
X
X   if(tptr->ren_name != NULL)`009`009/* need to deallocate rename name?    */
X   `123
V      str_size = (long) tptr->ren_len;`009/* length to deallocate `009      *
X/
X
X      status = LIB$FREE_VM(&str_size,&(tptr->ren_name));
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);
X
X      tptr->comm_ren = 0;`009`009/* make sure to shut of renaming      */
V      tptr->ren_name = NULL;`009`009/* reset the rename name stuff`009      *
X/
X      tptr->ren_len = 0;
X   `125
X
X   if(tptr->text != NULL)`009`009/* need to deallocate text descrip?   */
X   `123
V      str_size = (long) tptr->text_len;`009/* length to deallocate`009`009
X      */
X
X      status = LIB$FREE_VM(&str_size,&(tptr->text));
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);
X
X      tptr->comm_text = 0;`009`009/* make sure to shut of text descrip  */
X      tptr->text = NULL;`009`009/* reset the text descriptor stuff    */
X      tptr->text_len = 0;
X   `125
X
X   return(0);`009`009`009`009/* no problem.....`009`009      */
X
X`125`009/*** mark_delete ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:  `009mark_copy_ren
X
X  Purpose:  `009The selected file is to be copied or renamed; allocate the
X`009`009memory for the command structure (if necessary), link it to
X`009`009the file entry,`009and set the command in the command structure.
X
X  Global variables:
X                         `032
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`009completed successfully
X`009 -1`009`009`009problems allocating memory
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009return code from various failed system calls
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X  `032
Xshort mark_copy_ren(ent,pool,disp_id,keybd_id,pool_length,scr_width,command)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Vregister ENT_DEF  *ent;`009`009`009/* entry for file to be deleted`009      *
X/
X`009 POOL_DEF **pool;`009`009/* pointer to current pool structure  */
X`009 long`009  disp_id,`009`009/* display id for virtual display     */
X`009`009  keybd_id,`009`009/* keyboard id`009`009`009      */
X`009`009  pool_length;`009`009/* length of pool if we need another  */
X`009 short`009  scr_width;`009`009/* width of screen`009`009      */
X`009 char`009  command;`009`009/* either RENAME or COPY`009      */
X           `032
X`123`009/*** mark_copy_ren ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister COM_DEF  *tptr;`009`009/* temporary command structure ptr    */
X`009 char`009  *ptr,`009`009`009/* temporary character pointer`009      */
X`009`009  *dest_ptr;`009`009/* destination string pointer`009      */
X `009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 long`009  str_size;`009`009/* amount of memory to allocate`009      */
X`009 USHORT`009  length;`009`009/* length of string read in`009      */
X`009 char`009  buf[FULL_SPEC_MAX+1],`009/* array for new filename`009      */
X`009`009  prompt[PROMPT_MAX+1];`009/* prompt array`009`009`009      */
X
X
X   buf[0] = '\0';`009`009`009/* reset the buffer`009`009      */
X
X   /* set up the prompt for the filename */
X
X   if(command == COPY)
X      strcpy(prompt,"Copy to: ");
X   else
X      strcpy(prompt,"Rename to: ");
X
X   /* read in the file spec */
X
X   status = get_string(keybd_id,disp_id,FULL_SPEC_MAX,buf,prompt,scr_width);
X
X   if(status != SS$_NORMAL)
X      return(-1);
X
V   /* was anything specified for the filename?  if not, just return from here
X */
X
X   if(*buf == '\0')
X      return(0);
X
V   length = (USHORT)strlen(buf) + 1; `009/* don't forget to count the NUL`032
X     */
X
X   /* ok, we have a filename; now determine if we need to allocate a command
V    * structure for this file or if one already exists from a previous comman
Xd
X    */
X
X   if(ent->command == NULL)
X   `123
V      /* we need command structure; allocate it and link it to the file entry
X */
X           `032
X      tptr = new_comm();
X      if(tptr == NULL)
X`009 return(-1);`009`009`009/* problems allocating memory`009      */
X
X      ent->command = tptr;`009`009/* link it to the file entry`009      */
X   `125
X   else
X   `123
-+-+-+-+-+ End of part 7 +-+-+-+-+-

