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

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

+-+-+-+ Beginning of part 9 +-+-+-+
X`009`009*/
X
V`009       text_ptr = blnk_text;`009/* use a blank text descriptor`009      *
X/
X`009    `125
X`009 `125
X`009 else
X`009    text_ptr = nullptr;`009`009/* no text descriptor at all......    */
X
X`009 /* now make the slot, but don't include the size if we don't need it */
X
X      `009 if(args->size)`009`009/* should the size be included?`009      */
X`009 `123
X`009    sprintf(buf,"%s %6d %s %s %s",ent->scr_name,ent->size,
X`009`009    ent->date_str,prot_ptr,text_ptr);
X`009 `125
X`009 else
X`009 `123
X`009    sprintf(buf,"%s %s %s %s",ent->scr_name,ent->date_str,
X`009`009    prot_ptr,text_ptr);
X`009 `125
X      `125
X   `125
X
X   return(1);
X
X`125`009/*** make_slot ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009highlite
X
X  Purpose:`009Rewrite a slot entry for a file, highlighting it if it is
X`009`009necessary.  It will be highlighted if there are commands
X`009`009associated with the file entry.
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 highlite(disp_id,buf,ent,args,row,col,slot_width,text_flag)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 long`009  disp_id;`009`009/* display id of where to write`009      */
X`009 char`009  *buf;`009`009`009/* where to put the screen slot`009      */
Xregister ENT_DEF  *ent;`009`009`009/* file entry pointer`009`009      */
Xregister ARG_DEF  *args;`009`009/* run-time arguments`009`009      */
X`009 long`009  row,`009`009`009/* column to write it at`009      */
X`009`009  col;`009`009`009/* row to write it at`009`009      */
X`009 short`009  slot_width,`009`009/* width of screen slot`009`009      */
X`009`009  text_flag;`009`009/* whether we display text descrips   */
X
X`123`009/*** highlite ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
Vstatic`009 long`009  rend_set;`009`009/* rendition setting for slot entry   *
X/
Vstatic $DESCRIPTOR(slot_d,"");`009`009/* descriptor for writing the slot    *
X/
X
X
X   /* do we need bold or normal? */
X
X   if(make_slot(buf,ent,args,slot_width,text_flag) == 1)
X      rend_set = SMG$M_BOLD;
X   else
X      rend_set = SMG$M_NORMAL;
X
V   slot_d.dsc$a_pointer = buf;`009`009/* set up the descriptor for writing  *
X/
X   slot_d.dsc$w_length = (USHORT) strlen(buf);
X
X   status = SMG$PUT_CHARS(&disp_id,&slot_d,&row,&col,0,&rend_set,0,0);
X
X   return;
X
X`125`009/*** highlite ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009expand
X
X  Purpose:`009Expand a file entry by displaying all the information about
X`009`009the file that the user could possibly want.  Basically, all
X`009`009of the information from a DIR/FULL on the file is displayed,
X`009`009along with any of the commands that might be associated with
X`009`009the file.
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`009CANT_DISPLAY`009`009can't get file attributes to display
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xshort expand(ent,args,disp_id,paste_id,keybd_id,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister ENT_DEF  *ent;`009`009`009/* file entry pointer`009`009      */
X`009 ARG_DEF  *args;`009`009/* run-time arguments`009`009      */
X`009 ULONG`009  disp_id,`009`009/* display id to write to`009      */
X`009`009  paste_id,`009`009/* pasteboard id`009`009      */
X`009`009  keybd_id;`009`009/* keyboard id to read from`009      */
X`009 short`009  scr_width;`009`009/* width of screen`009`009      */
X
X`123`009/*** expand ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 COM_DEF  *comm_ptr;`009`009/* pointer to file commands for file  */
X`009 UIC_DEF  *uic;`009`009`009/* for splitting uic into owner/group */
X`009 ULONG`009  status;`009`009/* return code status`009`009      */
X`009 long`009  row = 1;`009`009/* what row is being written to`009      */
X`009 USHORT`009  timelen,`009`009/* length of date/time string`009      */
X`009`009  seq_flag = 0,`009`009/* flag set when file is sequential   */
X`009`009  term_code,`009`009/* character read from keyboard`009      */
X`009`009  temp0,`009`009/* temporary variable #1`009      */
X`009`009  temp1,`009`009/*    "          "    #2`009      */
X`009`009  temp2,`009`009/*    "`009`009 "    #3`009      */
X`009`009  temp3,`009`009/*    "`009`009 "    #4`009      */
X`009`009  *id_ptr;`009`009/* pointer to file id values`009      */
Xstatic`009 DATE_DEF *date_ptr;`009`009/* for checking date values`009      */
Vstatic`009 short`009  pass;`009`009`009/* whether we have been here before
X   */
Vstatic`009 UCHAR`009  acl_buf[ACLBUF_MAX];`009/* for holding ACL in binary`00
X9      */
Xstatic`009 char`009  buf[SCR_MAX*2],`009/* formatting buffer`009`009      */
X`009`009  buf2[SCR_MAX+1],`009/* another formatting buffer`009      */
X`009     `009  date1[DATE_TIME_MAX+1], /* for formatting date/time string  */
X   `009`009  date2[DATE_TIME_MAX+1]; /* ditto....`009`009`009      */
Vstatic`009 struct`009  FAB     fab;`009`009/* FAB for getting information`009
X      */
Vstatic`009 struct`009  NAM     in_nam;`009/* NAM  "     "         "`009  `032
X   */
Vstatic`009 struct`009  XABDAT  date_xab;`009/* XAB for dates/times`009`009
X      */
Vstatic`009 struct`009  XABPRO  prot_xab;`009/* XAB for getting protection, et
Xc.   */
Vstatic`009 struct`009  XABFHC  head_xab;`009/* XAB for file header`009`009
X      */
Xstatic`009 struct`009  XABSUM  sum_xab;`009/* XAB for summary`009`009      */
Xstatic`009 struct`009  dsc$descriptor_s
X`009`009  time_d =`009`009/* for making date/time string`009      */
X`123DATE_TIME_MAX,DSC$K_DTYPE_T,DSC$K_CLASS_S,NULL`125;
Vstatic $DESCRIPTOR(uic_d,buf2);`009`009/* descrip for translating UIC`009`032
X     */
Xstatic $DESCRIPTOR(prompt_d,"Press any key to continue                    \
X                                                                           \
X            ");
X
X
X   if(!pass)`009`009`009`009/* did we already initialize stuff?   */
X   `123
X      fab = cc$rms_fab;`009`009`009/* initialize all of the RMS blocks   */
X      in_nam = cc$rms_nam;
X      date_xab = cc$rms_xabdat;
X      prot_xab = cc$rms_xabpro;
X      head_xab = cc$rms_xabfhc;
X      sum_xab = cc$rms_xabsum;
X      fab.fab$l_nam = &in_nam;
X      fab.fab$l_xab = &date_xab;
X      date_xab.xab$l_nxt = &prot_xab;
X      prot_xab.xab$l_nxt = &head_xab;
X      head_xab.xab$l_nxt = &sum_xab;
X      prot_xab.xab$l_aclbuf = acl_buf;
X      prot_xab.xab$w_aclsiz = sizeof(acl_buf);
X      prompt_d.dsc$a_pointer[scr_width] = '\0';
X      pass = 1;`009`009`009`009/* make sure we do this only once     */
X   `125
X
X   memset((void *) &sum_xab,0,sizeof(sum_xab));
X   memset((void *) &date_xab,0,sizeof(sum_xab));
X   memset((void *) &prot_xab,0,sizeof(sum_xab));
X   memset((void *) &head_xab,0,sizeof(sum_xab));
X
X   fab.fab$l_fna = ent->filename;`009/* set up the filename in the FAB     */
X   fab.fab$b_fns = (UCHAR) strlen(ent->filename);
X   fab.fab$w_ifi = 0;`009`009`009/* reset just in case......`009      */
X
X   status = SYS$OPEN(&fab);`009`009/* open the file to get the info      */
X
X   /* did the file disappear before we could open it?  this could happen
X    * in very volatile directories where files are created and deleted
X    * all the time
X    */
X
X   if(status != RMS$_NORMAL)
X   `123
X      SYS$CLOSE(&fab);
X      return(CANT_DISPLAY);
X   `125
X
X   /* write the prompt to the virtual display */
X
V   status = SMG$PUT_CHARS(&disp_id,&prompt_d,&WORK_ROWS,&1L,0,&SMG$M_REVERSE,
X0,
X`009     `009`009  0);
X
X   if(status != SS$_NORMAL)
X   `123
X      SYS$CLOSE(&fab);`009`009`009/* abandon ship.....!`009`009      */
X      SMG$ERASE_DISPLAY(&disp_id);
X      return(CANT_DISPLAY);
X   `125
X
X   /* paste the work virtual display to the screen so we have something
X    * to write to
X    */
X
X   status = SMG$PASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id,&3,&1,0);
X
X   if(status != SS$_NORMAL)
X      return(CANT_DISPLAY);
X
X   /* now start creating the lines and writing them to the virtual display */
X
X   id_ptr = &in_nam.nam$w_fid;
X   temp1 = *id_ptr++;
X   temp2 = *id_ptr++;
X   temp3 = *id_ptr;
X   sprintf(buf2,"File Id:  (%d,%d,%d)",temp1,temp2,temp3);
X
X   /* is the filename so long that we have to write it by itself, or can
X    * we add the "File Id:" stuff at the end?
X    */
X
X   if(strlen(ent->filename) + strlen(buf2) + 5 > scr_width)
X   `123
X      /* we have to write them separately; write the filename first, letting
X       * put_buf wrap it where it sees fit
X       */
X
X      put_buf(keybd_id,disp_id,ent->filename,&row,scr_width,NULL,' ');
X
X      /* put in some tabs before writing the "File Id" line so that it
X       * will decent
X       */
X
X      cat(buf,"`009`009`009`009`009",buf2);
X      put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X   `125
X   else
X   `123
X      /* both of them will fit on one line; cat them together and send
X       * the result to put_buf
X       */
X      cat(buf,ent->filename,"     ",buf2);
X      put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X   `125
X
X   /* translate the owner uic to ASCII */
X
X   status = SYS$IDTOASC(prot_xab.xab$l_uic,&temp0,&uic_d,0,0,0);
X
X   if(status != SS$_NORMAL)
X   `123
V      /* oops, something went wrong; just use the numeric values for the memb
Xer
X       * and group for the translated UIC
X       */
X
X      uic = &(prot_xab.xab$l_uic);
X      sprintf(buf2,"%o,%o",uic->member,uic->group);
X   `125
X   else
X      buf2[temp0] = '\0';`009`009/* use what was translated`009      */
X
X   sprintf(buf,"Size:  %d/%d`009`009`009Owner: [%s]",ent->size,
X`009   head_xab.xab$l_hbk,buf2);
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   time_d.dsc$a_pointer = date1;`009/* set pointer to first date array    */
V   date_ptr = &(date_xab.xab$q_cdt);`009/* get a pointer to the date values
X   */
X
X   if(date_ptr->left `124`124 date_ptr->right)
X   `123
X      status = SYS$ASCTIM(&timelen,&time_d,date_ptr,0L);
X
X      if(status != SS$_NORMAL)
X      `123
X`009 SYS$CLOSE(&fab);`009`009/* abandon ship.....!`009`009      */
X         SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X`009 SMG$ERASE_DISPLAY(&disp_id);
X`009 return(CANT_DISPLAY);
X      `125
X
X      date1[DATE_MAX] = '\0';`009`009/* make it a string`009`009      */
X   `125
X   else
X      strcpy(date1,"<None specified>");
X
X   time_d.dsc$a_pointer = date2;`009/* now use the second date array      */
V   date_ptr = &(date_xab.xab$q_rdt);`009/* get a pointer to the date values
X   */
X
X   if(date_ptr->left `124`124 date_ptr->right)
X   `123
X      status = SYS$ASCTIM(&timelen,&time_d,date_ptr,0L);
X
X      if(status != SS$_NORMAL)
X      `123
X`009 SYS$CLOSE(&fab);`009`009/* abandon ship.....!`009`009      */
X         SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X`009 SMG$ERASE_DISPLAY(&disp_id);
X`009 return(CANT_DISPLAY);
X      `125
X
V      date2[DATE_MAX] = '\0';`009`009/* make it a string, too......`009  `032
X   */
X   `125
X   else
X      strcpy(date2,"<None specified>");
X
X   /* now make the line and display it */
X
X   sprintf(buf,"Created:  %s`009Revised:  %s (%d)",date1,date2,
X`009   date_xab.xab$w_rvn);
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   time_d.dsc$a_pointer = date1;`009/* set pointer to first date array    */
V   date_ptr = &(date_xab.xab$q_edt);`009/* get a pointer to the date values
X   */
X
X   if(date_ptr->left `124`124 date_ptr->right)
X   `123
X      status = SYS$ASCTIM(&timelen,&time_d,date_ptr,0L);
X            `032
X      if(status != SS$_NORMAL)
X      `123
X`009 SYS$CLOSE(&fab);`009`009/* abandon ship.....!`009`009      */
X         SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X`009 SMG$ERASE_DISPLAY(&disp_id);
X`009 return(CANT_DISPLAY);
X      `125
X
X      date1[DATE_MAX] = '\0';`009`009/* make it a string`009`009      */
X   `125
X   else
X      strcpy(date1,"<None specified>");
X
X   time_d.dsc$a_pointer = date2;`009/* now use the second date array      */
V   date_ptr = &(date_xab.xab$q_bdt);`009/* get a pointer to the date values
X   */
X
X   if(date_ptr->left `124`124 date_ptr->right)
X   `123
X      status = SYS$ASCTIM(&timelen,&time_d,date_ptr,0L);
X
X      if(status != SS$_NORMAL)
X      `123
X`009 SYS$CLOSE(&fab);`009`009/* abandon ship.....!`009`009      */
X         SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X`009 SMG$ERASE_DISPLAY(&disp_id);
X`009 return(CANT_DISPLAY);
X      `125
X
X      date2[DATE_MAX] = '\0';
X   `125
X   else
X      strcpy(date2,"<No backup done>");
X
X   /* now make the line and display it */
X
X   sprintf(buf,"Expires:  %s`009Backup:   %s",date1,date2);
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   sprintf(buf,"File organization:  ");
X      `032
X   switch(fab.fab$b_org)
X   `123
X      case(FAB$C_IDX):
X`009 strcat(buf,"Indexed");
X`009 break;
X
X      case(FAB$C_REL):
X`009 strcat(buf,"Relative");
X`009 break;
X
X      case(FAB$C_SEQ):
X`009 strcat(buf,"Sequential");
X`009 seq_flag = 1;`009`009`009/* file is sequential; set a flag     */
X`009 break;
X
X      default:
X`009 strcat(buf,"Sequential");
X`009 seq_flag = 1;`009`009`009/* file is sequential; set a flag     */
X`009 break;
X   `125
X
X   if(sum_xab.xab$w_pvn)
X   `123
X      sprintf(buf2,", Prolog: %d",sum_xab.xab$w_pvn);
X      strcat(buf,buf2);
X   `125
X
X   if(sum_xab.xab$b_nok)
X   `123
X      sprintf(buf2,", Using %d key(s)",sum_xab.xab$b_nok);
X      strcat(buf,buf2);
X   `125
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   sprintf(buf,"File attributes:    Allocation: %d, Extend: %d, Global \
Xbuffer count: %d,",head_xab.xab$l_hbk,head_xab.xab$w_dxq,head_xab.xab$w_gbc);
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
V   sprintf(buf,"                    Version limit: %d",head_xab.xab$w_verlimi
Xt);
X
X   if(fab.fab$l_fop & FAB$M_CTG)
X      strcat(buf,", Contiguous");
X
X   if(fab.fab$l_fop & FAB$M_CBT)
X      strcat(buf,", Contiguous best try");
X
X   if(fab.fab$l_fop & FAB$M_TEF)
X      strcat(buf,", Truncate");
X
X   if(strindex(ent->filename,".DIR;") >= 0)
X      strcat(buf,", Directory file");
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X   buf[0] = '\0';`009`009`009/* clear in case we don't use it      */
X
X   switch(fab.fab$b_rfm)`009`009/* determine record format`009      */
X   `123
X      case(FAB$C_FIX):
X`009 sprintf(buf,"Record format:      Fixed length %d byte records",
X`009`009 fab.fab$w_mrs);
X`009 break;
X
X      case(FAB$C_STMCR):
X`009 sprintf(buf,"Record format:      Stream_CR");
X`009 break;
X
X      case(FAB$C_STM):
X`009 sprintf(buf,"Record format:      Stream");
X`009 break;
X
X      case(FAB$C_STMLF):
X`009 sprintf(buf,"Record format:      Stream_LF");
X`009 break;
X
X      case(FAB$C_UDF):
X
X`009 if(head_xab.xab$w_lrl)
X`009    sprintf(buf,"Record format:      Undefined, maximum %d bytes",
X`009`009    head_xab.xab$w_lrl);
X`009 else
X`009    sprintf(buf,"Record format:      Undefined");
X
X`009 break;
X
X      case(FAB$C_VAR):
X
X`009 if(head_xab.xab$w_lrl)
X`009    sprintf(buf,"Record format:      Variable length, maximum %d bytes",
X`009`009    head_xab.xab$w_lrl);
X`009 else
X`009    sprintf(buf,"Record format:      Variable length");
X
X`009 break;
X
X      default:
X`009 break;
X   `125
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   sprintf(buf,"Record attributes:  ");
X
X   if(fab.fab$b_rat & FAB$M_CR)
X      strcat(buf,"Carriage return carriage control");
X   else if(fab.fab$b_rat & FAB$M_FTN)
X      strcat(buf,"FORTRAN carriage control ");
X   else if(fab.fab$b_rat & FAB$M_PRN)
X      strcat(buf,"Print carriage control ");
X   else
X   `123
X      if(fab.fab$b_rat != 0)
X      `123
X`009 strcat(buf,"No carriage control");
X`009 if(seq_flag)
X`009 `123
X`009    if(fab.fab$b_rat & FAB$M_BLK)
X`009       strcat(buf,", Non-spanned");
X`009    else
X`009       strcat(buf,", Spanned");
X`009 `125
X      `125
X     else
X`009 strcat(buf,"None");
X   `125
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   exp_prot_str(buf2,ent->prot);
X   sprintf(buf,"File protection:    %s",buf2);
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
V   if(prot_xab.xab$w_acllen != 0)`009/* is there an ACL to display?`009  `032
X   */
X   `123
X      /* format and display the ACL for the current file */
X
X      if(put_acl(keybd_id,&fab,&prot_xab,acl_buf,prot_xab.xab$w_acllen,&row,
X`009      disp_id,scr_width) != 0)
X`009 return(CANT_DISPLAY);
X   `125
X   else
X   `123
X      /* no ACL here; just say "None" (or is that "Just say NO"?  oh, right,
X       * that's for drugs.......)
X       */
X
V      put_buf(keybd_id,disp_id,"Access Cntrl List:  None",&row,scr_width,NULL
X,
X`009      ' ');
X   `125
X
X   if(args->text)`009`009`009/* does the user want text descrips?  */
X   `123
X      if(*ent->text == '\0')`009`009/* existing text descriptor?`009      */
X      `123
X`009 put_buf(keybd_id,disp_id,"Text descriptor:    None",&row,scr_width,
X`009      `009 NULL,' ');
X      `125
X      else
X      `123
X`009 sprintf(buf,"Text descriptor:    %s",ent->text);
X`009 put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X      `125
X   `125
X
X   /* now display any command that might be associated with the file */
X
X   sprintf(buf,"File Commands:");
X   row++;`009`009`009`009/* skip a line before writing`009      */
X
X   put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X
X   comm_ptr = ent->command;`009`009/* get pointer to commands`009      */
X
X   if(comm_ptr != NULL)`009`009`009/* are there any commands?`009      */
X   `123
X      /* yes, display them...... */
X
X      if(comm_ptr->comm_copy)
X      `123
X`009 /* display the filename specified for copying */
X
X`009 sprintf(buf,"   Copy to:  %s",comm_ptr->copy_name);
X`009 buf[scr_width] = '\0';`009`009/* truncate it if it is too long      */
X`009 put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X      `125
X
X      if(comm_ptr->comm_ren)
X      `123
X`009 /* display the filename specified for renaming */
X
X`009 sprintf(buf,"   Rename to:  %s",comm_ptr->ren_name);
X`009 buf[scr_width] = '\0';`009`009/* truncate it if it is too long      */
X`009 put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X      `125
X
X      if(comm_ptr->comm_prot)
X      `123
X`009 /* display the new protection value */
X
X`009 exp_prot_str(buf2,comm_ptr->prot);
X`009 sprintf(buf,"   Protection:  %s",buf2);
X`009 put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X      `125
X
X      if(comm_ptr->comm_text)
X      `123
X`009 /* display the text descriptor */
X
X`009 sprintf(buf,"   Text descriptor:  %s",comm_ptr->text);
X`009 put_buf(keybd_id,disp_id,buf,&row,scr_width,NULL,' ');
X      `125
X
X      if(comm_ptr->comm_del)
X      `123
X`009 /* display the fact that this file has been marked for deletion */
X
X`009 put_buf(keybd_id,disp_id,"   Delete",&row,scr_width,NULL,' ');
X      `125
X   `125
X   else
X   `123
X      /* no commands associated with this file */
X
X      put_buf(keybd_id,disp_id,"   None",&row,scr_width,NULL,' ');
X   `125
X                  `032
X   /* put the cursor at the second to last line in the first column and
X    * wait
X    */
X
X   status = SMG$SET_CURSOR_ABS(&disp_id,&(WORK_ROWS-1),&1L);
X
X   if(status != SS$_NORMAL)
X   `123
X      SYS$CLOSE(&fab);`009`009`009/* abandon ship.....!`009`009      */
X      SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X      SMG$ERASE_DISPLAY(&disp_id);
X      return(CANT_DISPLAY);
X   `125
X
X   /* now just wait for any character to be pressed */
X
X   status = SMG$READ_KEYSTROKE(&keybd_id,&term_code,0,0,&disp_id,0,0);
X
X   if((status != SS$_NORMAL) && (status != SMG$_EOF))
X   `123
X      SYS$CLOSE(&fab);`009`009`009/* abandon ship.....!`009`009      */
X      SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X      SMG$ERASE_DISPLAY(&disp_id);
X      return(CANT_DISPLAY);
X   `125
X
X   /* close the file */
X
X   SYS$CLOSE(&fab);
X
X   /* unpaste the work virtual display */
X
X   status = SMG$UNPASTE_VIRTUAL_DISPLAY(&disp_id,&paste_id);
X
X   if(status != SS$_NORMAL)
X      return(CANT_DISPLAY);
X
X   /* clear out the virtual display */
X
X   status = SMG$ERASE_DISPLAY(&disp_id);
X
X   return(0);
X
X`125`009/*** expand ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009xecute
X
X  Purpose:`009Execute all of the file commands for the current directory.
X`009`009Display success and failure messages to the screen for each
X`009`009of the files.
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 xecute(ent,args,in_buf,dir_text,disp_id,num_file,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
Xregister ENT_DEF  *ent;`009`009`009/* file entry pointer`009`009      */
X`009 ARG_DEF  *args;`009`009/* run-time argument flags`009      */
X`009 char`009  *in_buf,`009`009/* input buffer for copying`009      */
X`009`009  *dir_text;`009`009/* pointer to directory text descrip. */
X`009 ULONG`009  disp_id;`009`009/* display id for writing messages    */
X`009 short`009  num_file,`009`009/* number of files in directory`009      */
X`009`009  scr_width;`009`009/* width of screen display`009      */
X
X`123`009/*** xecute ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xregister ULONG`009  status;`009`009/* return code status`009`009      */
Vregister COM_DEF  *comm_ptr;`009`009/* pointer to command structure`009  `032
X   */
X`009 ULONG`009  status2,`009`009/* status code holder`009`009      */
X`009`009  status3,`009`009/*   "      "    "`009`009      */
X`009`009  status4;`009`009/*   "      "    "`009`009      */
X`009 long`009  size;`009`009`009/* size to be deallocated`009      */
X`009 short`009  i = 0,`009`009/* loop and array index`009`009      */
X`009`009  bad_text = 0;`009`009/* set if can't open text desc. file  */
Xstatic`009 struct`009  FAB`009  in_fab,`009/* input FAB`009`009`009      */
X`009`009`009  out_fab,`009/* output FAB`009`009`009      */
X`009`009`009  text_fab;`009/* text descriptor file FAB`009      */
Xstatic`009 struct`009  RAB`009  in_rab,`009/* input RAB`009`009`009      */
X`009`009`009  out_rab,`009/* output RAB`009`009`009      */
X`009`009`009  text_rab;`009/* text descriptor file RAB`009      */
Vstatic`009 struct`009  XABPRO  in_prot_xab,`009/* input protection XAB`009`00
X9      */
X`009`009`009  out_prot_xab; /* output protection XAB`009      */
Vstatic`009 UCHAR`009  pass;`009`009`009/* RMS block initialization flag  `032
X   */
Vstatic`009 char`009  buf[BUFSIZ],`009`009/* message formatting buffer`009`032
X     */
X`009`009  filename[FULL_SPEC_MAX+1];
X
X            `032
X   if(!pass)`009`009`009`009/* did we already initialize stuff?   */
X   `123
X      in_fab = cc$rms_fab;  `009`009/* initialize all of the RMS blocks   */
X      in_rab = cc$rms_rab;
X      out_fab = cc$rms_fab;
X      out_rab = cc$rms_rab;
X      in_prot_xab = cc$rms_xabpro;
X      out_prot_xab = cc$rms_xabpro;
X      in_fab.fab$l_xab = &in_prot_xab;
X      out_fab.fab$l_xab = &out_prot_xab;
X
V      in_fab.fab$b_fac = FAB$M_BIO `124`009/* block I/O for input file`009
X      */
X`009`009`009 FAB$M_GET;
X
V      out_fab.fab$b_fac = FAB$M_BIO `124`009/* block I/O for output file`009
X      */
X`009     `009`009  FAB$M_PUT;
X
X/*    out_fab.fab$l_dna = DEFAULT_FILESPEC;
X      out_fab.fab$b_dns = (USHORT) strlen(DEFAULT_FILESPEC); */
X      in_rab.rab$l_fab = &in_fab;`009/* pointer to input FAB`009`009      */
V      in_rab.rab$b_rac = RAB$C_SEQ;`009/* sequential access for copy`009 `032
X    */
X      in_rab.rab$w_usz = BUF_MAX;`009/* length of input buffer`009      */
X      in_rab.rab$l_ubf = in_buf;`009/* pointer to buffer`009`009      */
X
V      out_rab.rab$l_fab = &out_fab;`009/* pointer to input FAB`009`009      *
X/
V      out_rab.rab$b_rac = RAB$C_SEQ;`009/* sequential access for copy`009`032
X     */
X      out_rab.rab$w_usz = BUF_MAX;`009/* length of output buffer`009      */
X      out_rab.rab$l_rbf = in_buf;`009/* pointer to buffer`009`009      */
X      pass = 1;`009`009`009`009/* make sure we do this only once     */
X   `125                     `032
X
V   size = (long) sizeof(COM_DEF);`009/* length of command structure`009  `032
X   */
X
V   /* process all of the file commands for the files in the current directory
X */
X
X   while(i < num_file)
X   `123
V      if(ent->command != NULL)`009`009/* any commands for this file entry?  *
X/
X      `123
X`009 /* yes, now see what we need to do for this file */
X
X`009 comm_ptr = ent->command;`009/* get pointer to command structure   */
X`009 in_fab.fab$l_fna = ent->filename;
X`009 in_fab.fab$b_fns = (UCHAR) strlen(ent->filename);
X
X`009 if(comm_ptr->comm_copy)`009/* Copy command`009`009`009      */
X`009 `123
X`009    /* open the input file */
X
X`009    status = SYS$OPEN(&in_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&in_fab);
X`009       sprintf(buf,"Copy %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab1;
X`009    `125
X
X`009    /* connect the input file's RMS blocks */
X
X`009    status = SYS$CONNECT(&in_rab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&in_fab);
X`009       sprintf(buf,"Copy %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab1;
X`009    `125
X
X`009    out_fab = in_fab;`009`009/* copy the input file's FAB`009      */
X`009    out_fab.fab$w_ifi = 0;`009/* reset this!`009`009`009      */
X            out_fab.fab$b_fac = FAB$M_BIO `124 FAB$M_PUT;
X`009    out_fab.fab$l_xab = &out_prot_xab;
X
X`009    /* create the filename for the output file */
X
X`009    make_name(ent->filename,comm_ptr->copy_name,filename);
X
X`009    out_fab.fab$l_fna = filename;
X`009    out_fab.fab$b_fns = (UCHAR) strlen(filename);
X
X`009    /* which protection value do we use? */
X
X`009    if(comm_ptr->comm_prot)
X`009       out_prot_xab.xab$w_pro = comm_ptr->prot;
X`009    else
X`009       out_prot_xab.xab$w_pro = in_prot_xab.xab$w_pro;
X
X`009    /* open the output file */
X
X`009    status = SYS$CREATE(&out_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&out_fab);
X`009       SYS$CLOSE(&in_fab);`032
X`009       sprintf(buf,"Copy %s? *ERROR*\7",filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab1;
X`009    `125
X
X`009    /* connect the output file's RMS blocks */
X
X`009    status = SYS$CONNECT(&out_rab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&out_fab);
X`009       SYS$CLOSE(&in_fab);
X`009       sprintf(buf,"Copy %s? *ERROR*\7",filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab1;
X`009    `125
X
X            /* now copy the input file to the output file */
X
X`009    status = SYS$READ(&in_rab);
X`009    status2 = RMS$_NORMAL;`009/* have to lie to fool the loop`009      */
X
X`009    while((status == RMS$_NORMAL) && (status2 == RMS$_NORMAL))
X`009    `123
X`009       out_rab.rab$w_rsz = in_rab.rab$w_rsz;
X`009       status2 = SYS$WRITE(&out_rab);
X`009       status = SYS$READ(&in_rab);
X`009    `125
X
X`009    /* close both of the files */
X
X`009    status3 = SYS$CLOSE(&in_fab);
X`009    status4 = SYS$CLOSE(&out_fab);
X
X`009    /* did the loop terminate properly? if not, delete the output
X`009     * file and scream at the user
X`009     */
X
X`009    if((status != RMS$_EOF) `124`124 (status2 != RMS$_NORMAL) `124`124
X`009       (status3 != RMS$_NORMAL) `124`124 (status4 != RMS$_NORMAL))
X`009    `123
X`009       delete(comm_ptr->copy_name);
X`009       sprintf(buf,"Copy %s?  *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009    `125
X`009    else
X`009    `123
X`009       sprintf(buf,"Copy %s? [OK]",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009    `125
X`009 `125
X
Xlab1:`009 if(comm_ptr->comm_ren)`009`009/* Rename command`009`009      */
X`009 `123
X`009    /* create the filename for the output file */
X
X`009    make_name(ent->filename,comm_ptr->ren_name,filename);
X
X`009    out_fab.fab$l_fna = filename;
X`009    out_fab.fab$b_fns = (UCHAR) strlen(filename);
X`009    out_fab.fab$w_ifi = 0;
X
X`009    status = SYS$RENAME(&in_fab,0,0,&out_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       sprintf(buf,"Rename %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab2;`009`009/* sorry about this......`009      */
X`009    `125
X
X`009    /* should the renamed file have a new protection? */
X
X`009    if(comm_ptr->comm_prot)
X`009    `123
X`009       /* yes, reprotect the renamed file */
X
V`009       comm_ptr->comm_prot = 0;`009/* don't try to protect it after this
X */
X`009       out_fab.fab$w_ifi = 0;`009/* clear internal file identifier     */
X
X`009       status = SYS$OPEN(&out_fab);
X
X`009       if(status != RMS$_NORMAL)
X`009       `123
X`009`009  SYS$CLOSE(&out_fab);
X`009`009  sprintf(buf,"File %s renamed but set protection failed\7\7",
X`009`009`009  ent->filename);
X`009`009  xmess(disp_id,buf,scr_width);
X`009`009  sleep(1);
X`009`009  goto lab2;
X`009       `125
X
X`009       /* now insert the new protection before we close the file */
X
X`009       out_prot_xab.xab$w_pro = comm_ptr->prot;
X
X`009       status = SYS$CLOSE(&out_fab);
X
X`009       if(status != RMS$_NORMAL)
X`009       `123
X`009`009  sprintf(buf,"File %s renamed but set protection failed\7\7",
X`009`009`009  ent->filename);
X`009     `009  xmess(disp_id,buf,scr_width);
X`009`009  sleep(1);
X`009       `125
X`009    `125 /* if(comm_ptr->comm_prot) */
X
X`009    sprintf(buf,"Rename %s? [OK]",ent->filename);
X`009    xmess(disp_id,buf,scr_width);
X
X`009    /* look to see if there was a text descriptor for the file; if
X`009     * there was, write to text descriptor file record to make sure
X`009     * the old text descriptor follows the file to its new filename
X`009     */
X
X`009    if((ent->text != nullptr) && (!bad_text) && (!comm_ptr->comm_text))
X`009    `123
X`009       /* yes, write it to the text descriptor file */
X
X`009       make_text_rec(buf,comm_ptr->ren_name,ent->text);
X`009       status = write_text(&text_fab,&text_rab,buf,dir_text);
X
X`009       if(status != RMS$_NORMAL)
X`009`009  bad_text = 1;`009`009/* do not process text descr. anymore */
X
X`009       ent->text = nullptr;`009/* wipe out existing text descriptor  */
X`009    `125
X`009 `125
X
Xlab2:`009 if(comm_ptr->comm_prot)
X`009 `123
X`009    out_fab.fab$l_fna = ent->filename;
X`009    out_fab.fab$b_fns = (UCHAR) strlen(ent->filename);
X`009    out_fab.fab$w_ifi = 0;
X
X`009    status = SYS$OPEN(&out_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&out_fab);
X`009       sprintf(buf,"Protect %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab3;
X`009    `125
X
X`009    status = SYS$CONNECT(&out_rab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       SYS$CLOSE(&out_fab);
X`009       sprintf(buf,"Protect %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009       goto lab3;
X`009    `125
X
X`009    /* now insert the new protection before we close the file */
X
X`009    out_prot_xab.xab$w_pro = comm_ptr->prot;
X
X    `009    status = SYS$CLOSE(&out_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       sprintf(buf,"Protect %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009    `125
X`009    else
X`009    `123
X`009       sprintf(buf,"Protect %s? [OK]",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009    `125
X`009 `125
X
Xlab3:`009 if((comm_ptr->comm_text) && (!bad_text))
X`009 `123
X`009    /* is the text descriptor to be deleted?  if it is length zero,
X`009     * then it is;
X`009     */
X
X`009    if(strlen(comm_ptr->text) == 0)
X`009    `123
X`009       ent->text = nullptr;
X`009       goto lab4;
X`009    `125
X
X`009    /* now see which filename we should use; if the file is being
X`009     * renamed, use the new name
X`009     */
X
X`009    if(comm_ptr->comm_ren)
X`009       make_text_rec(buf,comm_ptr->ren_name,comm_ptr->text);
X`009    else
X`009       make_text_rec(buf,ent->filename,comm_ptr->text);
X
X`009    /* now write the text descriptor record to the file */
X
X`009    status = write_text(&text_fab,&text_rab,buf,dir_text);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       bad_text = 1;`009`009/* don't process any more text desc.  */
X`009       sprintf(buf,"Text %s? *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009    `125
X`009    else
X`009    `123
X`009       sprintf(buf,"Text %s? [OK]",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009    `125
X
X`009    ent->text = nullptr;`009/* clear out old text descriptor      */
X`009 `125
X
Xlab4:`009 if(comm_ptr->comm_del)
X`009 `123
X`009    /* set up the FAB first */
X
X`009    out_fab.fab$l_fna = ent->filename;
X`009    out_fab.fab$b_fns = (UCHAR) strlen(ent->filename);
X`009    out_fab.fab$w_ifi = 0;
X
X`009    status = SYS$ERASE(&out_fab);
X
X`009    if(status != RMS$_NORMAL)
X`009    `123
X`009       sprintf(buf,"Delete %s *ERROR*\7",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009       sleep(1);
X`009    `125
X`009    else
X`009    `123
X`009       sprintf(buf,"Delete %s? [OK]",ent->filename);
X`009       xmess(disp_id,buf,scr_width);
X`009    `125
X
X`009    ent->text = nullptr;`009/* clear out old text descriptor      */
X`009 `125
X
X`009 /* now free up the command structure for the file */
X
X`009 free_comstr(ent->command);     `032
X      `125
X
X      /* did the file have a text descriptor associated with it?  if it
X       * does at this point, we have to write it to the text descriptor file
X       */
X
X      if((ent->text != nullptr) && (!bad_text))
X      `123
X`009 /* yes, write it to the text descriptor file */
X
X`009 make_text_rec(buf,ent->filename,ent->text);
X`009 status = write_text(&text_fab,&text_rab,buf,dir_text);
X
X`009 if(status != RMS$_NORMAL)
X`009    bad_text = 1;`009`009/* do not process text descr. anymore */
X      `125
X
X      i++;`009`009`009`009/* count this file`009`009      */
X      ent++; `009`009`009`009/* go to next file entry`009      */
X   `125
X
X   buf[0] = '\0';`009`009`009/* end-of-file record for text desc.  */
X
X   status = write_text(&text_fab,&text_rab,buf,dir_text);
X
X   return;
X
X`125`009/*** xecute ***/    `032
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009xmess
X
X  Purpose:`009Display informational messages to the screen for files that
X`009`009are being manipulated during file command execution.
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 xmess(disp_id,buf,scr_width)
X`009`009`009`009   `009/*******   FORMAL  PARAMETERS   *******/
X`009 ULONG`009  disp_id;`009`009/* display id of where to write to    */
X`009 char`009  *buf;`009`009`009/* buffer to write to screen`009      */
X`009 short`009  scr_width;`009`009/* width of screen display`009      */
X
X`123`009/*** xmess ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
Xstatic $DESCRIPTOR(mess_d,"");`009`009/* output message buffer`009      */
X
X
X   /* first clear out things in case the new message is shorter than the
X    * previous one; we would have garbage at the end of it
X    */
X
V   clear_mess(disp_id,scr_width);`009/* clear the message line first`009 `032
X    */
X
X   mess_d.dsc$a_pointer = buf;`009`009/* set up the descriptor`009      */
X   mess_d.dsc$w_length = (USHORT) strlen(buf);
X
X   /* write the line to the display */
X
X   SMG$PUT_CHARS(&disp_id,&mess_d,&MAIN_ROWS,&1L,&1L,&SMG$M_REVERSE,0,0);
X
X   return;
X
X`125`009/*** xmess ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009tag_file
X
X  Purpose:`009Put a mark by a file on the screen so that user knows what
X`009`009file is being accessed when he is prompted at the bottom of
X`009`009the virtual display for information.  With the cursor at the
X`009`009bottom of the virtual display in preparation for receiving
X`009`009input, it is sometimes hard to remember what file was selected.
X`009`009This should help alleviate that.
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 tag_file(row,column,disp_id)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 long`009  row,`009`009`009/* row of where to write tag`009      */
X`009`009  column;`009`009/* column of where to write tag`009      */
X`009 ULONG`009  disp_id;`009`009/* display id to write to`009      */
X
X`123`009/*** tag_file ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
Vstatic $DESCRIPTOR(tag_d,">");`009`009/* char for tagging selected files    *
X/
X
X
X   status = SMG$PUT_CHARS(&disp_id,&tag_d,&row,&column,0,&SMG$M_BOLD,0,0);
X
X   return;
X
X`125`009/*** tag_file ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009erase_tag
X
X  Purpose:`009Erase a file tag now that user is done doing what they wanted
X`009`009with the file.
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 erase_tag(row,column,disp_id)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 long`009  row,`009`009`009/* row of where to write tag`009      */
X`009`009  column;`009`009/* column of where to write tag`009      */
X`009 ULONG`009  disp_id;`009`009/* display id to write to`009      */
X
X`123`009/*** erase_tag ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
Vstatic $DESCRIPTOR(tag_d," ");`009`009/* blank for wiping out tag character *
X/
X
X
X   status = SMG$PUT_CHARS(&disp_id,&tag_d,&row,&column,0,0,0,0);
X
X   return;
X
X`125`009/*** erase_tag ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009put_text
X
X  Purpose:`009Put the text descriptor for the directory on the screen.
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`009Everything fine
X`009 -1`009`009`009Error parsing new filename
X
X  Termination Codes:
X
X`009Code`009`009`009Reason
X`009----`009`009`009------
X`009status`009`009`009unable to display directory text descriptor
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xvoid put_text(disp_id,text_desc,scr_width)
X      `009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ULONG`009  disp_id;`009`009/* display id to write to`009      */
X`009 char`009  *text_desc; `009`009/* text descriptor buffer`009      */
X`009 short`009  scr_width;`009`009/* width of screen being used`009      */
X
X`123`009/*** put_text ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 short`009  length;`009`009/* string length holder`009`009      */
Xstatic`009 char`009  buf[SCR_MAX+5],`009/* formatting buffer`009`009      */
X`009`009  spaces[] =`009`009/* spaces array for centering stuff   */
X"                                                                    ";
Vstatic $DESCRIPTOR(text_d,buf);`009`009/* descriptor for writing to screen
X   */
X
X
X   if(text_desc != NULL)`009`009/* is there anything to write?`009      */
X   `123
X      length = (scr_width - (short) strlen(text_desc))/2;
V      spaces[length] = '\0';  `009`009/* make spaces for centering`009      *
X/
V      cat(buf,spaces,text_desc,spaces," "); /* make a string to write`009`032
X     */
X      buf[scr_width] = '\0';`009`009/* make sure we have the right length */
X      spaces[length] = ' ';`009`009/* reset spaces array for next time   */
X
V      text_d.dsc$w_length = scr_width;`009/* set length in descriptor`009`032
X     */
X
X      status = SMG$PUT_CHARS(&disp_id,&text_d,&2L,&1L,0,&SMG$M_REVERSE,0,0);
X
X      if(status != SS$_NORMAL)
X         LIB$STOP(status);
X   `125
X   else
X   `123
X      /* erase the one that might be on the screen, since this directory
X       * doesn't have a text descriptor
X       */
X
X      status = SMG$ERASE_DISPLAY(&disp_id,&2L,&1L);
X
X      if(status != SS$_NORMAL)
X`009 LIB$STOP(status);
X   `125
X
X   return;
X
X`125`009/*** put_text ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009info_mess
X
X  Purpose:`009Display an informational message on the screen
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`009unable to display screen message
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xvoid info_mess(disp_id,message,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ULONG`009  disp_id;`009`009/* where to write it`009`009      */
X`009 char`009  *message;`009`009/* message to be written`009      */
X`009 short`009  scr_width;`009`009/* width of screen`009`009      */
X
X`123`009/*** info_mess ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 long`009  start_row;`009`009/* row to start writing at`009      */
Xstatic`009 struct`009  dsc$descriptor_s
X`009`009  text_d;`009`009/* output descriptor`009`009      */
X
X   /* first clear out things in case the new message is shorter than the
X    * previous one; we would have garbage at the end of it
X    */
X
V   clear_mess(disp_id,scr_width);`009/* clear the message line first`009 `032
X    */
X
X   /* set up the descriptor for the message */
X
X   text_d.dsc$a_pointer = message;
X   text_d.dsc$w_length = (USHORT) strlen(message);
X   start_row = MAIN_ROWS;
X   status = SMG$PUT_CHARS(&disp_id,&text_d,&start_row,&1L,0,&SMG$M_BOLD,0,0);
X
X   if(status != SS$_NORMAL)
X      LIB$STOP(status);
X
X   return;
X
X`125`009/*** info_mess ***/
X/*eject*/
V/****************************************************************************
X***
V*****************************************************************************
X***
X
X  Function:`009create_text
X
X  Purpose:`009Attempt to create the text descriptor file if the user wants
X`009`009to.  The user is prompted for the text descriptor for the
X`009`009directory and the file is written with the entry for the
X`009`009text descriptor file itself.
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`009DONT_CREATE`009`009user does not want text descriptor file created
X`009CANT_OPEN`009`009error opening/writing text descriptor file
X`009NEW_FILE`009`009new text descriptor file created
X
V*****************************************************************************
X***
V*****************************************************************************
X**/
X
Xshort create_text(keybd_id,disp_id,scr_width)
X`009`009`009`009`009/*******   FORMAL  PARAMETERS   *******/
X`009 ULONG`009  keybd_id,`009`009/* keyboard id to read from`009      */
X`009 `009  disp_id;`009`009/* display id of where to prompt      */
X`009 short`009  scr_width;`009`009/* screen width`009`009`009      */
X
X`123`009/*** create_text ***/
X`009`009`009`009`009/********   LOCAL  VARIABLES   ********/
X`009 ULONG`009  status;`009`009/* return code status holder`009      */
X`009 USHORT`009  term_code,`009`009/* keystroke read in`009`009      */
X`009`009  length;`009`009/* length of string read in`009      */
Vstatic`009 struct`009  FAB  out_fab;`009`009/* text descriptor file FAB`009
X      */
Vstatic`009 struct`009  RAB  out_rab;`009`009/* text descriptor file RAB`009
X      */
Vstatic`009 char`009  prompt[] =`009`009/* prompt for directory text descrip
X  */
X`009`009  `123"Text descriptor for directory: "`125,
X`009`009  buf[SCR_MAX+1],`009/* for all kinds of output stuff      */
X`009`009  text_buf[DIR_TEXT_MAX+1]; /* buffer for reading from screen */
Vstatic $DESCRIPTOR(text_d,text_buf);`009/* descriptor for reading from screen
X */
Xstatic $DESCRIPTOR(prompt_d,prompt);
X
X
X   sprintf(buf,"Text descriptor file %s does not exist.  Create it? [y] ",
X`009   TEXT_FILE);
X
V   /* prompt the user to see if they want to create the text descriptor file
X */
X
X   info_mess(disp_id,buf,scr_width);
X
X   /* read the keystroke for their response */
X
X   status = SMG$READ_KEYSTROKE(&keybd_id,&term_code,0,0,&disp_id,0,0);
X
X   clear_mess(disp_id,scr_width);`009/* clear the prompt from the screen   */
X
X   /* now see what key was pressed */
X
X   if(status != SS$_NORMAL)`009`009/* `094Z maybe....??`009`009      */
X      return(DONT_CREATE);`009`009/* do not create file`009`009      */
-+-+-+-+-+ End of part 9 +-+-+-+-+-

