
DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 1
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)



    1        	/******************************************************
    2        	*                                                                       
    3        	* Copyright (c) Digital Equipment Corporation, 1980 - 1996
    4        	*
    5        	*	DFU Disk and File Utilities for OPENVMS
    6        	*	Version V2.4
    7        	*	Freeware version
    8        	*	Date : august 1996
    9        	********************************************************/
   10        	
   11        	#ifndef VAXC
   12        	#pragma message disable(GLOBALEXT)
   13        	#endif
   14        	
   15        	#include clidef         
  461        	#include climsgdef
  807        	#include descrip
 1783        	#include stdio
 2459        	#include lib$routines
 4228        	#include prvdef
 4412        	#include ssdef
 5903        	#include jpidef
 6159        	#include smgdef
 6998        	#include signal
 7495        	#include tt2def
 7633        	#include iodef
 8608        	typedef unsigned long Boolean;
 8609        	
 8610        	globalvalue dfu_tables;
 8611        	/* Next global params needed for CTRL/C trapping */
 8612        	
 8613        	int key_tab, status, cip, orig_colls;
 8614        	static int orgttchar[3], ttchar[3];
 8615        	
 8616        	extern char outbuf[255];
 8617        	extern unsigned int ctrlc, tchan, disp_id, disp1_id, rows, colls,
 8618        	disp2_id, status_id, paste_id, help_id, keyb_id;
 8619        	extern Boolean smg$enable;
 8620        	
 8621        	static FILE *xp;
 8622        	int astrtn(), refresh() ; /* Ast routines called by CTRLC,Y and W */
 8623        	unsigned int prim_hand(), brdcst_ast();
 8624        	void singlemsg(),put_disp(), put_status();
 8625        	
 8626        	main()
 8627        	
 8628        	/*	MAIN 
 8629        	
 8630        		Purpose : 1 Get privilege mask
 8631        			  2 Setup SMG environment unless no VT or DFU$NOSMG is set
 8632        			  3 Get and Parse command (syntax only)
 8633        			  4 Dispatch to correct subroutine
 8634        	
 8635        		Inputs  : Command line (if specified through foreign command)
 8636        	

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 2
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8637        		Outputs : returns last status code to DCL in  case
 8638        			  of single command processing. In interactive mode
 8639        			  always returns SS$_NORMAL.
 8640        	*/
 8641        	{
 8642        	  const rms_eof=98938,smg$_eof=1213442;
 8643        	  struct { 
 8644        	    short status, count; 
 8645        	    int extra ;
 8646        	  } 
 8647        	  iosb;
 8648        	  static char command_line[255], *e;
 8649        	  unsigned int out_len,ret_len,prvmask;
 8650        	  void reset_ctrl(), clean_ctrlc(), 
 8651        	  prev_screen(), next_screen(), dump_screen(), toggle_width() ;
 8652        	  int smg_flag, x, y, i, ttype;
 8653        	  int cursor_on = SMG$M_CURSOR_ON;
 8654        	  $DESCRIPTOR(input_line , command_line);
 8655        	  $DESCRIPTOR(prompt,"DFU> ");
 8656        	  $DESCRIPTOR(terminal,"SYS$COMMAND");
 8657        	  $DESCRIPTOR(top_txt,"< DFU V2.4 (Freeware) >");
 8658        	  $DESCRIPTOR(status_txt,"Statistics");
 8659        	  $DESCRIPTOR(do_key,"DO");
 8660        	  $DESCRIPTOR(pf2,"PF2");
 8661        	  $DESCRIPTOR(pf4,"PF4");
 8662        	  $DESCRIPTOR(prev,"PREV_SCREEN");
 8663        	  $DESCRIPTOR(next,"NEXT_SCREEN");
 8664        	  $DESCRIPTOR(select,"SELECT");
 8665        	  $DESCRIPTOR(help,"HELP");
 8666        	
 8667        	  /* First find out how we got called ( by RUN, or a foreign command */
 8668        	  ret_len = 0;
 8669        	  status = lib$get_foreign(&input_line,0,&ret_len,0); 
 8670        	  out_len = ret_len; 
 8671        	
 8672        	  smg$enable = TRUE;
 8673        	  key_tab = 0; 
 8674        	  disp2_id = 0; 
 8675        	  cip = 0;
 8676        	
 8677        	  /* Now create the SMG environment */
 8678        	
 8679        	  colls=80;
 8680        	  SMG$CREATE_PASTEBOARD(&paste_id, 0, &rows, 
 8681        	  &colls,&SMG$M_KEEP_CONTENTS,&ttype,0);
 8682        	  if ((e = (char *) getenv("DFU$NOSMG")) && *e) 
 8683        	  { 
 8684        	    smg$enable = FALSE;
 8685        	    SMG$DELETE_PASTEBOARD(&paste_id,&0);
 8686        	  }
 8687        	  else
 8688        	  { 
 8689        	    if (ttype != SMG$K_VTTERMTABLE) smg$enable = FALSE;
 8690        	    if (ttype != SMG$K_VTTERMTABLE) SMG$DELETE_PASTEBOARD(&paste_id,&0);
 8691        	  }
 8692        	
 8693        	  SMG$CREATE_VIRTUAL_KEYBOARD(&keyb_id,0,0,0,0);

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 3
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8694        	  if (smg$enable)
 8695        	    /* Setup key table */
 8696        	  { 
 8697        	    SMG$ERASE_PASTEBOARD(&paste_id);
 8698        	    SMG$CREATE_KEY_TABLE(&key_tab); 
 8699        	    colls -=2; 
 8700        	    orig_colls = colls;
 8701        	    smg_flag = SMG$M_KEY_NOECHO + SMG$M_KEY_TERMINATE;
 8702        	    SMG$ADD_KEY_DEF(&key_tab,&do_key,0, &smg_flag, &do_key,0);
 8703        	    SMG$ADD_KEY_DEF(&key_tab,&pf4,0, &smg_flag,&pf4,0);
 8704        	    SMG$ADD_KEY_DEF(&key_tab,&prev,0, &smg_flag, &prev,0);
 8705        	    SMG$ADD_KEY_DEF(&key_tab,&next,0, &smg_flag, &next,0);
 8706        	    SMG$ADD_KEY_DEF(&key_tab,&pf2,0, &smg_flag, &help,0); 
 8707        	    SMG$ADD_KEY_DEF(&key_tab,&help,0, &smg_flag, &help,0); 
 8708        	    SMG$ADD_KEY_DEF(&key_tab,&select,0, &smg_flag, &select,0); 
 8709        	    SMG$CREATE_VIRTUAL_DISPLAY(&500, &colls , &disp1_id, &SMG$M_BORDER, 
 8710        	    0, 0);
 8711        	    x = 508 - rows; 
 8712        	    y = rows - 7;
 8713        	    SMG$CREATE_VIEWPORT(&disp1_id,&x,&1,&y,&colls); 
 8714        	    SMG$CREATE_VIRTUAL_DISPLAY(&2, &colls, &status_id, 0 , 0, 0);
 8715        	    SMG$CREATE_VIRTUAL_DISPLAY(&2, &colls, &disp2_id, 0 , 0, 0);
 8716        	    SMG$SET_BROADCAST_TRAPPING(&paste_id,brdcst_ast,0);
 8717        	    SMG$LABEL_BORDER(&disp1_id, &top_txt, 0, 0,&SMG$M_BOLD);
 8718        	    SMG$LABEL_BORDER(&status_id, &status_txt, 0, 0,&SMG$M_BOLD);
 8719        	    SMG$PASTE_VIRTUAL_DISPLAY(&disp1_id, &paste_id, &2,&2,0);
 8720        	    x = rows - 4;
 8721        	    SMG$PASTE_VIRTUAL_DISPLAY(&status_id, &paste_id, &x,&2,0);
 8722        	    x = rows - 1;
 8723        	    SMG$PASTE_VIRTUAL_DISPLAY(&disp2_id, &paste_id, &x,&2,0);
 8724        	    x = 508 - rows;
 8725        	    SMG$SET_CURSOR_ABS(&disp1_id,&x,&1);  
 8726        	    SMG$SET_CURSOR_ABS(&disp2_id,&1,&1);  
 8727        	    SMG$BEGIN_PASTEBOARD_UPDATE(&paste_id);
 8728        	  }
 8729        	
 8730        	  sprintf(outbuf,"\n     Disk and File Utilities for OpenVMS DFU V2.4");
 8731        	  put_disp();
 8732        	  sprintf(outbuf,"     Freeware version");
 8733        	  put_disp();
 8734        	  sprintf(outbuf,"     Copyright © 1996 Digital Equipment Corporation\n");
 8735        	  put_disp();
 8736        	
 8737        	  if (smg$enable)
 8738        	  { /* Enter additional info */
 8739        	    sprintf(outbuf,"     DFU functions are : \n"); 
 8740        	    put_disp();
 8741        	    sprintf(outbuf,"     DEFRAGMENT : Defragment files"); 
 8742        	    put_disp();
 8743        	    sprintf(outbuf,"     DELETE     : Delete files by File-ID; delete directory (trees)"); 
 8744        	    put_disp();
 8745        	    sprintf(outbuf,"     DIRECTORY  : Manipulate directories"); 
 8746        	    put_disp();
 8747        	    sprintf(outbuf,"     REPORT     : Generate a complete disk report"); 
 8748        	    put_disp();
 8749        	    sprintf(outbuf,"     SEARCH     : Fast file search"); 
 8750        	    put_disp();

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 4
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8751        	    sprintf(outbuf,"     SET        : Modify file attributes"); 
 8752        	    put_disp();
 8753        	    sprintf(outbuf,"     UNDELETE   : Recover deleted files"); 
 8754        	    put_disp();
 8755        	    sprintf(outbuf,"     VERIFY     : Check and repair disk structure"); 
 8756        	    put_disp();
 8757        	    SMG$END_PASTEBOARD_UPDATE(&paste_id);
 8758        	  }  
 8759        	
 8760        	  prvmask = 0;
 8761        	  status = dfu_check_access(&prvmask);  /*Get the privilege mask */
 8762        	
 8763        	  /* Setup terminal channel for control purposes; get the terminal chars */
 8764        	  status = SYS$ASSIGN(&terminal, &tchan, 0,0);
 8765        	  status = SYS$QIOW(0,tchan, IO$_SENSEMODE,0,0,0,&orgttchar,12,0,0,0,0);
 8766        	  for (i = 0; i < 3; i++) ttchar[i] = orgttchar[i];
 8767        	  ttchar[2] &= ~TT2$M_EDITING; /* Clear line edit bit */
 8768        	  clean_ctrlc(); /* Enable CTRL/W if needed */
 8769        	
 8770        	  if (ret_len==0) 
 8771        	  { 
 8772        	    if (smg$enable) 
 8773        	      status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line,&prompt,
 8774        	      &out_len,&disp2_id,0,0,0,0,0);
 8775        	    else 
 8776        	      status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line,&prompt,
 8777        	      &out_len,0,0,0,0,0,0);
 8778        	  }
 8779        	
 8780        	  cip = 1;
 8781        	
 8782        	  /* Main loop starts here. Get a command and pasre it*/
 8783        	  for (;;)
 8784        	  { /* loop forever until EXIT is entered */
 8785        	    if(status==smg$_eof) status = exit_command(prvmask);
 8786        	    if ((status&1) != 1) goto endfor;
 8787        	    if (out_len == 0) goto endfor;
 8788        	
 8789        	    /* First catch special screen commands */
 8790        	    if (smg$enable)
 8791        	    { 
 8792        	      status = strncmp(command_line, "PREV_SCREEN", 11);
 8793        	      if (status == 0) 
 8794        	      { 
 8795        	        prev_screen();
 8796        	        goto endfor;
 8797        	      }     
 8798        	      status = strncmp(command_line, "DO",2);
 8799        	      if (status == 0) 
 8800        	      { 
 8801        	        status = spawn_command(prvmask);
 8802        	        goto endfor;
 8803        	      }     
 8804        	      status = strncmp(command_line, "PF4",3);
 8805        	      if (status == 0) 
 8806        	      { 
 8807        	        dump_screen();

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 5
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8808        	        goto endfor;
 8809        	      }     
 8810        	      status = strncmp(command_line, "NEXT_SCREEN", 11);
 8811        	      if (status == 0) 
 8812        	      { 
 8813        	        next_screen();
 8814        	        goto endfor;
 8815        	      }     
 8816        	      status = strncmp(command_line, "SELECT", 6);
 8817        	      if (status == 0)
 8818        	      { 
 8819        	        toggle_width();
 8820        	        goto endfor;
 8821        	      }
 8822        	
 8823        	      SMG$ERASE_DISPLAY(&disp1_id);
 8824        	      SMG$ERASE_DISPLAY(&status_id);
 8825        	      SMG$CHANGE_VIEWPORT(&disp1_id,&x,&1,&y,&colls);
 8826        	      SMG$SET_CURSOR_ABS(&disp1_id,&x,&1);  
 8827        	    }
 8828        	
 8829        	    /* Catch the CLI errors do avoid disrupting the SMG screen... */
 8830        	    VAXC$ESTABLISH(prim_hand);
 8831        	    status = CLI$DCL_PARSE(&input_line,dfu_tables,lib$get_input,0,&prompt);
 8832        	    VAXC$ESTABLISH(NULL);
 8833        	    if (status == CLI$_NOCOMD) singlemsg(0,status);
 8834        	    if ((status & 1 ) != 1) goto endfor;
 8835        	    else
 8836        	      /* Now dispatch if no errors */
 8837        	    { 
 8838        	      reset_ctrl();
 8839        	      CLI$DISPATCH(prvmask);
 8840        	      clean_ctrlc();
 8841        	      cip = 0;
 8842        	      status = brdcst_ast();
 8843        	      if (smg$enable) SMG$SET_CURSOR_MODE(&paste_id, &cursor_on);
 8844        	    }
 8845        	endfor:
 8846        	    if (ret_len !=0) 
 8847        	    { /* Single command processing , so exit here */
 8848        	      status += 0x10000000; /* Do not echo the error on DCL level */
 8849        	      if (smg$enable) 
 8850        	      { 
 8851        	        if (colls != orig_colls) toggle_width();
 8852        	        SMG$SET_CURSOR_ABS(&disp2_id,&2,&1);  
 8853        	      }
 8854        	      exit(status);
 8855        	    }
 8856        	    /* Get next line */
 8857        	    cip = 0;
 8858        	    if (smg$enable)
 8859        	    { 
 8860        	      SMG$ERASE_LINE(&disp2_id, &1, &1);
 8861        	      SMG$SET_CURSOR_ABS(&disp2_id,&1,&1);  
 8862        	      status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line,
 8863        	      &prompt,&out_len,&disp2_id,0,0,0,0,0); /*Get next command */
 8864        	      cip = 1;

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 6
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8865        	    }
 8866        	    else
 8867        	      status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line,
 8868        	      &prompt,&out_len,0,0,0,0,0,0); /*Get next command */
 8869        	  }
 8870        	}  /* END of MAIN */
 8871        	
 8872        	int help_command(int mask)
 8873        	/*	HELP
 8874        	
 8875        		Purpose : call on-line help
 8876        		Output  : contents of DFUHLP helplib.
 8877        	*/
 8878        	{  
 8879        	  unsigned int x,flag=1,tmp=0;
 8880        	  static char help[80];
 8881        	  $DESCRIPTOR(help_key ,help);
 8882        	  $DESCRIPTOR(help_item, "helpkey");
 8883        	  $DESCRIPTOR(help_lib,"dfuhlp");
 8884        	  $DESCRIPTOR(item,"DFU ");
 8885        	  $DESCRIPTOR(hlp_txt,"< DFU Help Screen >");
 8886        	
 8887        	  /* Check if a help item was entered */
 8888        	  if (cli$present(&help_item) == CLI$_PRESENT) 
 8889        	    cli$get_value(&help_item,&help_key,&help_key);
 8890        	  else
 8891        	    help_key.dsc$w_length=0;
 8892        	
 8893        	  /* Add 'DFU ' to the help key */
 8894        	  help_key.dsc$w_length +=4;
 8895        	  str$concat(&help_key,&item,&help_key);
 8896        	  x = rows - 4;
 8897        	  /* Reenable line editing... */
 8898        	  status = SYS$QIOW(0,tchan, IO$_SETMODE,0,0,0,&orgttchar,12,0,0,0,0);
 8899        	  if (smg$enable)
 8900        	  { 
 8901        	    SMG$CREATE_VIRTUAL_DISPLAY(&x, &colls, &help_id, 0 , 0, 0);
 8902        	    SMG$LABEL_BORDER(&help_id, &hlp_txt, 0, 0,&SMG$M_BOLD);
 8903        	    SMG$PASTE_VIRTUAL_DISPLAY(&help_id, &paste_id, &2,&2,0);
 8904        	    status = SMG$PUT_HELP_TEXT(&help_id, &keyb_id, &help_key, &help_lib,0,0);
 8905        	    SMG$UNPASTE_VIRTUAL_DISPLAY(&help_id, &paste_id);
 8906        	    SMG$DELETE_VIRTUAL_DISPLAY(&help_id);
 8907        	  }
 8908        	  else
 8909        	    status = lbr$output_help(lib$put_output,0,&help_key,
 8910        	    &help_lib,&flag,lib$get_input);
 8911        	  if (status != SS$_NORMAL)
 8912        	  { 
 8913        	    sprintf(outbuf,"%%DFU-E-HELPERR, Error opening help library,");
 8914        	    put_disp(); 
 8915        	    singlemsg(0,status);
 8916        	  }
 8917        	  return(1);
 8918        	} /*END help_command */
 8919        	
 8920        	int exit_command(int mask)
 8921        	/*  EXIT

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 7
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8922        	
 8923        		Purpose : Exit Program with SS$_NORMAL
 8924        		Output  : Return to DCL
 8925        	
 8926        	*/
 8927        	{  
 8928        	  void clean_ctrlc(), toggle_width();
 8929        	
 8930        	  clean_ctrlc(); 
 8931        	  if (smg$enable)
 8932        	  { 
 8933        	    SMG$DISABLE_BROADCAST_TRAPPING(&paste_id);
 8934        	    if (colls != orig_colls) toggle_width();
 8935        	    SMG$SET_CURSOR_ABS(&disp2_id,&2,&1);  
 8936        	    SMG$DELETE_PASTEBOARD(&paste_id, &0);
 8937        	  }
 8938        	  exit(1);
 8939        	  return(1);
 8940        	} /*END exit_command */
 8941        	
 8942        	int spawn_command(int mask)
 8943        	{
 8944        	  /* Saves the screen and spawns a subprocess */
 8945        	
 8946        	  int save_id;
 8947        	  $DESCRIPTOR(prompt,"DFU_sub$ ");
 8948        	
 8949        	  if (smg$enable)
 8950        	  { 
 8951        	    SMG$SAVE_PHYSICAL_SCREEN(&paste_id, &save_id);
 8952        	    SMG$DISABLE_BROADCAST_TRAPPING(&paste_id);
 8953        	  }
 8954        	  printf("%%DFU-I-SPAWN, Creating subprocess...\n");
 8955        	  status = lib$spawn(0,0,0,0,0,0,0,0,0,0,&prompt,0,0);
 8956        	  /* Next call is a workaround for a bug in TTdriver which may inadvertently
 8957        	     reset the terminal width */
 8958        	  if (colls > 80) printf("\x1b[?3h");      
 8959        	  else printf("\x1b[?3l");
 8960        	  if (smg$enable)
 8961        	  { 
 8962        	    SMG$RESTORE_PHYSICAL_SCREEN(&paste_id, &save_id);
 8963        	    SMG$SET_BROADCAST_TRAPPING(&paste_id,brdcst_ast,0);
 8964        	  }
 8965        	  if ((status & 1) !=1) singlemsg(0,status);
 8966        	  return (1);
 8967        	}
 8968        	
 8969        	void prev_screen(void)
 8970        	{
 8971        	  int row_start, cnt;
 8972        	
 8973        	  SMG$GET_VIEWPORT_CHAR(&disp1_id, &row_start);
 8974        	  cnt = row_start - 1;
 8975        	  if (cnt <= 1)
 8976        	    SMG$RING_BELL(&disp1_id);
 8977        	  else
 8978        	    if (cnt < (rows - 10))

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 8
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 8979        	    { 
 8980        	      SMG$SCROLL_VIEWPORT(&disp1_id, &SMG$M_DOWN, &cnt);
 8981        	    }
 8982        	    else
 8983        	    { 
 8984        	      cnt = (rows - 10);
 8985        	      SMG$SCROLL_VIEWPORT(&disp1_id, &SMG$M_DOWN, &cnt);
 8986        	    }
 8987        	}
 8988        	
 8989        	void next_screen(void)
 8990        	{
 8991        	  int row_start, cnt;
 8992        	
 8993        	  SMG$GET_VIEWPORT_CHAR(&disp1_id, &row_start);
 8994        	  cnt = 508 - rows - row_start;
 8995        	  if (cnt <= 1)
 8996        	    SMG$RING_BELL(&disp1_id);
 8997        	  else
 8998        	    if (cnt < (rows - 10))
 8999        	    { 
 9000        	      SMG$SCROLL_VIEWPORT(&disp1_id, &SMG$M_UP, &cnt);
 9001        	    }
 9002        	    else
 9003        	    { 
 9004        	      cnt = (rows - 10);
 9005        	      SMG$SCROLL_VIEWPORT(&disp1_id, &SMG$M_UP, &cnt);
 9006        	    }
 9007        	}
 9008        	
 9009        	int dump_actn(struct dsc$descriptor *out_str, int user_arg)
 9010        	{  
 9011        	  fprintf(xp,"%.*s\n",out_str->dsc$w_length, out_str->dsc$a_pointer);
 9012        	  return(1);
 9013        	}
 9014        	
 9015        	void dump_screen(void)
 9016        	/* Routine to dump the screen contents to a file */
 9017        	{ 
 9018        	  char fname[]="DFU_SCREEN.TXT";
 9019        	
 9020        	  xp = fopen(fname,"w","mrs=132","rfm=var","ctx=rec","rat=cr","rop=WBH");
 9021        	  status = SMG$PUT_PASTEBOARD(&paste_id, dump_actn, 0 , 0);
 9022        	  if ((status & 1) !=1)
 9023        	  { 
 9024        	    sprintf(outbuf,"%%DFU-E-DUMPERR, Error dumping screen contents,");
 9025        	    put_disp(); 
 9026        	    singlemsg(0, status);
 9027        	  }
 9028        	  else
 9029        	  { 
 9030        	    sprintf(outbuf,"%%DFU-I-DUMPDONE, Screen contents saved in DFU_SCREEN.TXT");
 9031        	    put_disp(); 
 9032        	  }
 9033        	  fclose(xp);
 9034        	}
 9035        	

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 9
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 9036        	void toggle_width(void)
 9037        	/* Routine to change terminal width */
 9038        	{
 9039        	  if (colls > 80)
 9040        	    SMG$CHANGE_PBD_CHARACTERISTICS(&paste_id, &80, &colls);
 9041        	  else           
 9042        	    SMG$CHANGE_PBD_CHARACTERISTICS(&paste_id, &132, &colls);
 9043        	  colls -=2;
 9044        	  SMG$CHANGE_VIRTUAL_DISPLAY(&disp1_id,0,&colls);
 9045        	  SMG$CHANGE_VIEWPORT(&disp1_id,0,0,0,&colls);
 9046        	  SMG$CHANGE_VIRTUAL_DISPLAY(&status_id,0,&colls);
 9047        	  SMG$CHANGE_VIRTUAL_DISPLAY(&disp2_id,0,&colls);
 9048        	}
 9049        	
 9050        	int dfu_check_access(int *mask)
 9051        	/*
 9052        	    Check if the user has DFU_ALLPRIV identifier granted.
 9053        	    Check also for VOLPRO priv (needed for INDEXF command )
 9054        	*/
 9055        	
 9056        	{ 
 9057        	  int i,j, rights_size, ret_addr, pages;
 9058        	  unsigned short len;
 9059        	  int jpi$_rights_size , jpi$_process_rights;
 9060        	  union prvdef jpiprv;
 9061        	  struct _itm { 
 9062        	    short buflen, itemcode;
 9063        	    int *bufadr, *retlen; 
 9064        	  } 
 9065        	  item_list[3];
 9066        	  struct _rt {
 9067        	    int rights[2]; 
 9068        	  } 
 9069        	  *rights_list;
 9070        	  static char ascii_id[255]; 
 9071        	  $DESCRIPTOR(ascii_descr , ascii_id);
 9072        	  Boolean found;
 9073        	
 9074        	  jpi$_rights_size = 817; 
 9075        	  jpi$_process_rights = 814;
 9076        	  *mask = 0; /*Assume identifier not granted */
 9077        	  item_list[0].buflen = 4;
 9078        	  item_list[0].itemcode = jpi$_rights_size;
 9079        	  item_list[0].bufadr = &rights_size;
 9080        	  item_list[0].retlen = 0;
 9081        	
 9082        	  item_list[1].buflen = 0;
 9083        	  item_list[1].itemcode = 0; /* End of list */
 9084        	  status = SYS$GETJPIW(0,0,0,&item_list,0,0,0);
 9085        	  if ((status & 1) !=1) 
 9086        	  { 
 9087        	    singlemsg(0,status);
 9088        	    return(status);
 9089        	  }
 9090        	  /* Rightssize is returned in bytes, so rightssize/8 -1 is
 9091        	     number of rights. Now allocate enough dynamic space to get
 9092        	     all the rights in. */

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 10
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 9093        	
 9094        	  j = (rights_size/8) + 1;
 9095        	  ret_addr = malloc(j*8);
 9096        	  rights_list = (struct _rt *) ret_addr;
 9097        	
 9098        	  item_list[0].buflen = j*8 ;
 9099        	  item_list[0].itemcode = jpi$_process_rights;
 9100        	  item_list[0].bufadr = (int *) rights_list; 
 9101        	  item_list[0].retlen = 0;
 9102        	
 9103        	  item_list[1].buflen = sizeof(jpiprv);
 9104        	  item_list[1].itemcode = JPI$_CURPRIV;
 9105        	  item_list[1].bufadr = (int *) &jpiprv;
 9106        	  item_list[1].retlen = 0;
 9107        	
 9108        	  item_list[2].buflen = 0;
 9109        	  item_list[2].itemcode = 0; /* End of list */
 9110        	
 9111        	  memset(&jpiprv,0,sizeof(jpiprv));
 9112        	  status = SYS$GETJPIW(0,0,0,&item_list,0,0,0);
 9113        	  if ((status & 1) !=1)
 9114        	  { 
 9115        	    singlemsg(0,status);
 9116        	    return(status);
 9117        	  }
 9118        	  i = 1; 
 9119        	  found = FALSE; 
 9120        	  while (!found)
 9121        	  { 
 9122        	    status = SYS$IDTOASC(rights_list->rights[0], &len, &ascii_descr, 0,0,0);
 9123        	    status = strncmp(ascii_id, "DFU_ALLPRIV", len);
 9124        	    if (status == 0) 
 9125        	    { 
 9126        	      *mask = -1;
 9127        	      found = TRUE;
 9128        	    }
 9129        	    else 
 9130        	    { 
 9131        	      i++; 
 9132        	      rights_list++;
 9133        	      if (i > j) found = TRUE;
 9134        	    }
 9135        	  }
 9136        	  free(ret_addr);
 9137        	  if ((jpiprv.prv$v_volpro ==1 ) && (*mask == -1)) *mask = -2;
 9138        	  return(1);
 9139        	}
 9140        	
 9141        	void reset_ctrl(void)
 9142        	/* Reset CTRLC/Y on the terminal channel */
 9143        	
 9144        	{
 9145        	  int stat, func;
 9146        	  struct { 
 9147        	    short status, count; 
 9148        	    int extra ;
 9149        	  } 

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 11
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 9150        	  iosb;
 9151        	  unsigned int t_mask[2];
 9152        	
 9153        	  /* Disable the F6 key */
 9154        	  status = SYS$QIOW(0,tchan, IO$_SETMODE,0,0,0,&ttchar,12,0,0,0,0);
 9155        	  ctrlc = 0;
 9156        	  /* Enable CTRLC/Y trapping by setting CTRL C and Y as out-of-band chars*/
 9157        	  t_mask[0] = 0; 
 9158        	  t_mask[1] = 1 << 3;
 9159        	  t_mask[1] += (1 << 25); 
 9160        	  status = SYS$QIOW(0,tchan,(IO$_SETMODE+IO$M_OUTBAND),&iosb,
 9161        	  0,0,astrtn,&t_mask,0,0,0,0); 
 9162        	}
 9163        	
 9164        	int astrtn()
 9165        	/* Ast routine called by CTRLC/Y 
 9166        	   Set CTRLC to 1 and reset the Trapping */
 9167        	
 9168        	{ 
 9169        	  ctrlc = 1;
 9170        	  SMG$CANCEL_INPUT(&keyb_id);
 9171        	  sprintf(outbuf,"     Current command ABORTING...");
 9172        	  put_status(2);
 9173        	  return(1);
 9174        	}
 9175        	
 9176        	void clean_ctrlc()
 9177        	/* Cleanup CTRLC channel */
 9178        	
 9179        	{ 
 9180        	  struct { 
 9181        	    short status, count; 
 9182        	    int extra ;
 9183        	  } 
 9184        	  iosb;
 9185        	  unsigned int t_mask[2];
 9186        	
 9187        	  status = SYS$QIOW(0,tchan, IO$_SETMODE,0,0,0,&orgttchar,12,0,0,0,0); 
 9188        	  if (!smg$enable)
 9189        	    status = SYS$QIOW(0,tchan,(IO$_SETMODE+IO$M_OUTBAND),&iosb,
 9190        	    0,0,0,0,0,0,0,0); 
 9191        	  else
 9192        	  { 
 9193        	    t_mask[0] = 0; 
 9194        	    t_mask[1] = 1 << 23;
 9195        	    status = SYS$QIOW(0,tchan,(IO$_SETMODE+IO$M_OUTBAND),&iosb,
 9196        	    0,0,refresh,&t_mask,0,0,0,0); 
 9197        	  }
 9198        	  status = 1;
 9199        	}
 9200        	
 9201        	int refresh()
 9202        	{
 9203        	  status = SMG$CANCEL_INPUT(&keyb_id);
 9204        	  status = SMG$REPAINT_SCREEN(&paste_id);
 9205        	  return(1);
 9206        	}

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 12
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 9207        	
 9208        	int strindex(char *input_string, char *symbol, int len)
 9209        	/*
 9210        	   Search for a char in input_string.
 9211        	*/
 9212        	
 9213        	{ 
 9214        	  int i ;
 9215        	
 9216        	  i=0;
 9217        	  while ((i < len) && (input_string[i] != *symbol)) i++;
 9218        	  return(i < len ) ? i : -1; 
 9219        	}
 9220        	
 9221        	void put_status(int x)
 9222        	/* Display statistics info */
 9223        	
 9224        	{
 9225        	  $DESCRIPTOR(stat_descr, outbuf);
 9226        	  if (smg$enable)
 9227        	  { 
 9228        	    stat_descr.dsc$w_length = strlen(outbuf);
 9229        	    SMG$PUT_CHARS(&status_id, &stat_descr, &x, &2, &SMG$M_ERASE_LINE);
 9230        	  }
 9231        	}
 9232        	
 9233        	void put_disp(void)
 9234        	/* Put result line on screen */
 9235        	{
 9236        	  $DESCRIPTOR(to_disp, outbuf);
 9237        	
 9238        	  if (smg$enable)
 9239        	  { 
 9240        	    to_disp.dsc$w_length = strlen(outbuf);
 9241        	    SMG$PUT_LINE(&disp1_id, &to_disp,0,0,0,&SMG$M_WRAP_CHAR,0,0);
 9242        	  }
 9243        	  else printf("%s\n",outbuf);
 9244        	}
 9245        	
 9246        	void singlemsg(int stat1, int stat)
 9247        	/* Gets a system message and displays it.
 9248        	   Unlike LIB$SIGNAL it will not terminate the
 9249        	   program on fatal errors 
 9250        	*/
 9251        	{
 9252        	  int len;                                               
 9253        	  $DESCRIPTOR(mesg_desc , outbuf);
 9254        	
 9255        	  if (stat1 !=0)
 9256        	  { 
 9257        	    SYS$GETMSG(stat1,&mesg_desc.dsc$w_length, &mesg_desc,0,0);
 9258        	    outbuf[mesg_desc.dsc$w_length]='\0';
 9259        	    put_disp(); 
 9260        	    mesg_desc.dsc$w_length = 255;
 9261        	  }
 9262        	  SYS$GETMSG(stat,&mesg_desc.dsc$w_length, &mesg_desc,0,0);
 9263        	  outbuf[mesg_desc.dsc$w_length]='\0';

DFU                                                             13-AUG-1996 10:23:40    DEC C      V5.2-003                 Page 13
V1.0                                                            13-AUG-1996 10:23:37    OWN$:[SOURCES.CC.DFUSRC.FREE024]DFU.C;3 (1)

 9264        	  put_disp(); 
 9265        	  mesg_desc.dsc$w_length = 255;
 9266        	}
 9267        	
 9268        	int actrtn(struct dsc$descriptor *out_str, int user_arg)
 9269        	/* user action routine to catch SYS$PUTMSG errors*/
 9270        	{ 
 9271        	  sprintf(outbuf,"%.*s",out_str->dsc$w_length, out_str->dsc$a_pointer);
 9272        	  put_disp();
 9273        	  return(0);
 9274        	}
 9275        	
 9276        	unsigned int prim_hand(signal, mech)
 9277        	int signal[], mech[];
 9278        	{ /* Use the signal array to pass the error to PUTMSG
 9279        	     PUTMSG in turn will call ACTRTN which will use SMG output
 9280        	     in stead of just dumping SYS$OUTPUT/ERROR
 9281        	  */
 9282        	
 9283        	  int params;
 9284        	  signal[0] -= 2;
 9285        	  SYS$PUTMSG(signal, actrtn,0,params);
 9286        	  return SS$_CONTINUE;
 9287        	}
 9288        	
 9289        	unsigned int brdcst_ast()
 9290        	/* Displays the broadcast messages */
 9291        	{ 
 9292        	  static char msg[255];
 9293        	  unsigned short len;
 9294        	  $DESCRIPTOR(brdcst_msg,msg);
 9295        	
 9296        	  len = 0;
 9297        	  if (cip == 1) return(1); /* exit if DFU is busy */
 9298        	  status = SMG$CANCEL_INPUT(&keyb_id);
 9299        	  SMG$SET_CURSOR_ABS(&status_id,&2,&2); 
 9300        	  status = SMG$GET_BROADCAST_MESSAGE(&paste_id, &brdcst_msg, &len,0);
 9301        	  SMG$BEGIN_PASTEBOARD_UPDATE(&paste_id);
 9302        	  while (status == SS$_NORMAL)
 9303        	  { 
 9304        	    brdcst_msg.dsc$w_length = len+1;
 9305        	    SMG$PUT_LINE(&disp1_id, &brdcst_msg, 0, 0 ,0 ,&SMG$M_WRAP_CHAR, 0, 0);
 9306        	    brdcst_msg.dsc$w_length = 254;
 9307        	    status = SMG$GET_BROADCAST_MESSAGE(&paste_id, &brdcst_msg, &len,0);
 9308        	  }
 9309        	  SMG$END_PASTEBOARD_UPDATE(&paste_id);
 9310        	  return(1);
 9311        	}

 
 
Command Line
------------
 
CC/DECC/EXTERN=COMMON/SHARE/WARN=NOINFO DFU/LIS

