main(int argc, char *argv[]) /* MAIN Purpose : 1 Get privilege mask 2 Setup SMG environment unless no VT or DFU$NOSMG is set 3 Get and Parse command (syntax only) 4 Dispatch to correct subroutine Inputs : Command line (if specified through foreign command) Outputs : returns last status code to DCL in case of single command processing. In interactive mode always returns SS$_NORMAL. */ { const rms_eof=98938,smg$_eof=1213442; struct { short status, count; int extra ; } iosb; static char command_line[255], *e; unsigned int out_len,ret_len,prvmask; void reset_ctrl(), clean_ctrlc(), prev_screen(), next_screen(), dump_screen(), toggle_width() ; int smg_flag, x, y, i, ttype; int cursor_on = SMG$M_CURSOR_ON; $DESCRIPTOR(input_line , command_line); $DESCRIPTOR(prompt,"DFU> "); $DESCRIPTOR(terminal,"SYS$COMMAND"); $DESCRIPTOR(top_txt,"< DFU V2.2 (Freeware) >"); $DESCRIPTOR(status_txt,"Statistics"); $DESCRIPTOR(do_key,"DO"); $DESCRIPTOR(pf2,"PF2"); $DESCRIPTOR(pf4,"PF4"); $DESCRIPTOR(prev,"PREV_SCREEN"); $DESCRIPTOR(next,"NEXT_SCREEN"); $DESCRIPTOR(select,"SELECT"); $DESCRIPTOR(help,"HELP"); /* First find out how we got called ( by RUN, or a foreign command */ ret_len = 0; #if 0 status = lib$get_foreign(&input_line,0,&ret_len,0); #else status = 1; #if 0 strcpy(command_line,argv[1]); #endif #endif out_len = ret_len; smg$enable = TRUE; key_tab = 0; disp2_id = 0; cip = 0; setvbuf(stdout, NULL, _IONBF, 0); // need this to see i/o at all #if 0 smg$enable = FALSE; vms_mm = check_vms_mm(); #else /* Now create the SMG environment */ colls=80; rows=24; SMG$CREATE_PASTEBOARD(&paste_id, 0, &rows, &colls,&SMG$M_KEEP_CONTENTS,&ttype,0); if ((e = (char *) getenv("DFU$NOSMG")) && *e) smg$enable = FALSE; else { if (ttype != SMG$K_VTTERMTABLE) smg$enable = FALSE; if (ttype != SMG$K_VTTERMTABLE) SMG$DELETE_PASTEBOARD(&paste_id,&i0); } SMG$CREATE_VIRTUAL_KEYBOARD(&keyb_id,0,0,0,0); if (smg$enable) /* Setup key table */ { SMG$ERASE_PASTEBOARD(&paste_id, 0, 0, 0, 0, 0, 0); SMG$CREATE_KEY_TABLE(&key_tab); colls -=2; orig_colls = colls; smg_flag = SMG$M_KEY_NOECHO + SMG$M_KEY_TERMINATE; SMG$ADD_KEY_DEF(&key_tab,&do_key,0, &smg_flag, &do_key,0); SMG$ADD_KEY_DEF(&key_tab,&pf4,0, &smg_flag,&pf4,0); SMG$ADD_KEY_DEF(&key_tab,&prev,0, &smg_flag, &prev,0); SMG$ADD_KEY_DEF(&key_tab,&next,0, &smg_flag, &next,0); SMG$ADD_KEY_DEF(&key_tab,&pf2,0, &smg_flag, &help,0); SMG$ADD_KEY_DEF(&key_tab,&help,0, &smg_flag, &help,0); SMG$ADD_KEY_DEF(&key_tab,&select,0, &smg_flag, &select,0); SMG$CREATE_VIRTUAL_DISPLAY(&i500, &colls , &disp1_id, &SMG$M_BORDER, 0, 0); x = 508 - rows; y = rows - 7; SMG$CREATE_VIEWPORT(&disp1_id,&x,&i1,&y,&colls); SMG$CREATE_VIRTUAL_DISPLAY(&i2, &colls, &status_id, 0 , 0, 0); SMG$CREATE_VIRTUAL_DISPLAY(&i2, &colls, &disp2_id, 0 , 0, 0); SMG$SET_BROADCAST_TRAPPING(&paste_id,brdcst_ast,0); SMG$LABEL_BORDER(&disp1_id, &top_txt, 0, 0,&SMG$M_BOLD, 0, 0); SMG$LABEL_BORDER(&status_id, &status_txt, 0, 0,&SMG$M_BOLD, 0, 0); SMG$PASTE_VIRTUAL_DISPLAY(&disp1_id, &paste_id, &i2,&i2,0); x = rows - 4; SMG$PASTE_VIRTUAL_DISPLAY(&status_id, &paste_id, &x,&i2,0); x = rows - 1; SMG$PASTE_VIRTUAL_DISPLAY(&disp2_id, &paste_id, &x,&i2,0); x = 508 - rows; SMG$SET_CURSOR_ABS(&disp1_id,&x,&i1); SMG$SET_CURSOR_ABS(&disp2_id,&i1,&i1); SMG$BEGIN_PASTEBOARD_UPDATE(&paste_id); } #endif sprintf(outbuf,"\n Disk and File Utilities for OpenVMS DFU V2.2"); put_disp(); sprintf(outbuf," Freeware version"); put_disp(); sprintf(outbuf," Copyright © 1995 Digital Equipment Corporation\n"); put_disp(); if (smg$enable) { /* Enter additional info */ sprintf(outbuf," DFU functions are : \n"); put_disp(); sprintf(outbuf," DEFRAGMENT : Defragment files"); put_disp(); sprintf(outbuf," DELETE : Delete files by File-ID; delete directory (trees)"); put_disp(); sprintf(outbuf," DIRECTORY : Manipulate directories"); put_disp(); sprintf(outbuf," REPORT : Generate a complete disk report"); put_disp(); sprintf(outbuf," SEARCH : Fast file search"); put_disp(); sprintf(outbuf," SET : Modify file attributes"); put_disp(); sprintf(outbuf," UNDELETE : Recover deleted files"); put_disp(); sprintf(outbuf," VERIFY : Check and repair disk structure"); put_disp(); SMG$END_PASTEBOARD_UPDATE(&paste_id); } prvmask = 0; status = dfu_check_access(&prvmask); /*Get the privilege mask */ /* Setup terminal channel for control purposes; get the terminal chars */ status = SYS$ASSIGN(&terminal, &tchan, 0,0); status = SYS$QIOW(0,tchan, IO$_SENSEMODE,0,0,0,&orgttchar,12,0,0,0,0); for (i = 0; i < 3; i++) ttchar[i] = orgttchar[i]; ttchar[2] &= ~TT2$M_EDITING; /* Clear line edit bit */ clean_ctrlc(); /* Enable CTRL/W if needed */ if (ret_len==0) { if (smg$enable) status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line,&prompt, &out_len,&disp2_id,0,0,0,0,0); else status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line,&prompt, &out_len,0,0,0,0,0,0); } memcpy (command_line, input_line.dsc$a_pointer, input_line.dsc$w_length); cip = 1; /* Main loop starts here. Get a command and pasre it*/ for (;;) { /* loop forever until EXIT is entered */ if(status==smg$_eof) status = exit_command(prvmask); if ((status&1) != 1) goto endfor; if (out_len == 0) goto endfor; /* First catch special screen commands */ if (smg$enable) { status = strncmp(command_line, "PREV_SCREEN", 11); if (status == 0) { prev_screen(); goto endfor; } status = strncmp(command_line, "DO",2); if (status == 0) { status = spawn_command(prvmask); goto endfor; } status = strncmp(command_line, "PF4",3); if (status == 0) { dump_screen(); goto endfor; } status = strncmp(command_line, "NEXT_SCREEN", 11); if (status == 0) { next_screen(); goto endfor; } status = strncmp(command_line, "SELECT", 6); if (status == 0) { toggle_width(); goto endfor; } SMG$ERASE_DISPLAY(&disp1_id, 0, 0, 0, 0); SMG$ERASE_DISPLAY(&status_id, 0, 0, 0, 0); SMG$CHANGE_VIEWPORT(&disp1_id,&x,&i1,&y,&colls); SMG$SET_CURSOR_ABS(&disp1_id,&x,&i1); } /* Catch the CLI errors do avoid disrupting the SMG screen... */ #if 0 VAXC$ESTABLISH(prim_hand); #endif status = CLI$DCL_PARSE(&input_line,&dfu_tables,0 /* not yet lib$get_input*/,0,&prompt); // check added & before dfu_tables #if 0 VAXC$ESTABLISH(NULL); #endif if (status == CLI$_NOCOMD) singlemsg(0,status); if ((status & 1 ) != 1) goto endfor; else /* Now dispatch if no errors */ { reset_ctrl(); CLI$DISPATCH(prvmask); clean_ctrlc(); cip = 0; status = brdcst_ast(); if (smg$enable) SMG$SET_CURSOR_MODE(&paste_id, &cursor_on); } endfor: if (ret_len !=0) { /* Single command processing , so exit here */ status += 0x10000000; /* Do not echo the error on DCL level */ if (smg$enable) { if (colls != orig_colls) toggle_width(); SMG$SET_CURSOR_ABS(&disp2_id,&i2,&i1); } exit(status); } /* Get next line */ cip = 0; #if 1 if (smg$enable) { SMG$ERASE_LINE(&disp2_id, &i1, &i1); SMG$SET_CURSOR_ABS(&disp2_id,&i1,&i1); status = SMG$READ_COMPOSED_LINE(&keyb_id,&key_tab,&input_line, &prompt,&out_len,&disp2_id,0,0,0,0,0); /*Get next command */ cip = 1; } else status = SMG$READ_COMPOSED_LINE(&keyb_id,0,&input_line, &prompt,&out_len,0,0,0,0,0,0); /*Get next command */ #else printf("%s",prompt.dsc$a_pointer); out_len = read(0,command_line,254); out_len--; command_line[out_len]=0; if (strncmp(command_line,"exit",4)==0) return 0; #endif } } /* END of MAIN */
char * readpassphrase(const char *prompt, char *pbuf, size_t buflen, int flags) { static unsigned long keyboard_id, keytable_id = 0; unsigned long ctrl_mask, saved_ctrl_mask = 0; int timeout_secs = 0; int *timeout_ptr = NULL; unsigned long status = 0; unsigned short iosb[4]; unsigned short ttchan, result_len = 0, stdin_is_tty; $DESCRIPTOR(ttdsc, ""); $DESCRIPTOR(pbuf_dsc, ""); $DESCRIPTOR(prompt_dsc, ""); char *retval = NULL; char *myprompt = NULL; char input_fspec[MY_PASSWORD_LEN + 1]; if (pbuf == NULL || buflen == 0) { errno = EINVAL; return NULL; } bzero(pbuf, buflen); pbuf_dsc.dsc$a_pointer = pbuf; pbuf_dsc.dsc$w_length = buflen - 1; /* * If stdin is not a terminal and only reading from a terminal is allowed, we * stop here. */ stdin_is_tty = isatty(fileno(stdin)); if (stdin_is_tty != 1 && (flags & RPP_REQUIRE_TTY)) { errno = ENOTTY; return NULL; } /* * We need the file or device associated with stdin in VMS format. */ if (fgetname(stdin, input_fspec, 1)) { ttdsc.dsc$a_pointer = (char *)&input_fspec; ttdsc.dsc$w_length = strlen(input_fspec); } else { errno = EMFILE; return NULL; } /* * The prompt is expected to provide its own leading newline. */ myprompt = malloc(strlen(prompt) + 1); if (myprompt == NULL) { errno = ENOMEM; return NULL; } sprintf(myprompt, "\n%s", prompt); prompt_dsc.dsc$a_pointer = myprompt; prompt_dsc.dsc$w_length = strlen(myprompt); if (!(flags & RPP_ECHO_ON) && (stdin_is_tty)) { /* Disable Ctrl-T and Ctrl-Y */ ctrl_mask = LIB$M_CLI_CTRLT | LIB$M_CLI_CTRLY; status = LIB$DISABLE_CTRL(&ctrl_mask, &saved_ctrl_mask); if (!$VMS_STATUS_SUCCESS(status)) { errno = EVMSERR; vaxc$errno = status; free(myprompt); return NULL; } } /* * Unless timeouts are disabled, find out how long should we wait for input * before giving up. */ if (!(flags & RPP_TIMEOUT_OFF)) { unsigned long tmo_item = SYI$_LGI_PWD_TMO; status = LIB$GETSYI(&tmo_item, &timeout_secs); if (!$VMS_STATUS_SUCCESS(status)) timeout_secs = DEFAULT_TIMEOUT; timeout_ptr = &timeout_secs; } if (!(flags & RPP_ECHO_ON) && (stdin_is_tty)) { /* * If we are suppressing echoing, get a line of input with $QIOW. * Non-echoed lines are not stored for recall. (The same thing * could be done with SMG but would require maintenance of a virtual * display and pasteboard.) */ status = SYS$ASSIGN(&ttdsc, &ttchan, 0, 0, 0); if ($VMS_STATUS_SUCCESS(status)) { unsigned long qio_func = IO$_READPROMPT | IO$M_NOECHO | IO$M_PURGE; if (!(flags & RPP_TIMEOUT_OFF)) qio_func |= IO$M_TIMED; bzero(iosb, sizeof(iosb)); status = SYS$QIOW(0, (unsigned long) ttchan, qio_func, &iosb, 0, 0, pbuf, buflen - 1, timeout_secs, 0, myprompt, strlen(myprompt)); if ($VMS_STATUS_SUCCESS(status)) { status = iosb[0]; result_len = iosb[1]; /* bytes actually read */ } (void) SYS$DASSGN(ttchan); } } else { /* * We are not suppressing echoing because echoing has been explicitly * enabled and/or we are not reading from a terminal. In this case we * use SMG, which will store commands for recall. The virtual keyboard * and key table are static and will only be created if we haven't been * here before. */ status = SS$_NORMAL; if (keyboard_id == 0) { unsigned char recall_size = RECALL_SIZE; status = SMG$CREATE_VIRTUAL_KEYBOARD(&keyboard_id, &ttdsc, 0, 0, &recall_size); } if ($VMS_STATUS_SUCCESS(status) && keytable_id == 0) { status = SMG$CREATE_KEY_TABLE(&keytable_id); } if ($VMS_STATUS_SUCCESS(status)) { status = SMG$READ_COMPOSED_LINE(&keyboard_id, &keytable_id, &pbuf_dsc, &prompt_dsc, &result_len, 0, 0, 0, timeout_ptr); } } /* * Process return value from SYS$QIOW or SMG$READ_COMPOSED_LINE. */ switch (status) { case SS$_TIMEOUT: errno = ETIMEDOUT; break; case SMG$_EOF: if (result_len != 0) { status = SS$_NORMAL; } /* fall through */ default: if ($VMS_STATUS_SUCCESS(status)) { int i; if (flags & RPP_FORCELOWER) { for (i = 0; i < result_len; i++) pbuf[i] = tolower(pbuf[i]); } if (flags & RPP_FORCEUPPER) { for (i = 0; i < result_len; i++) pbuf[i] = toupper(pbuf[i]); } if (flags & RPP_SEVENBIT) { for (i = 0; i < result_len; i++) pbuf[i] &= 0x7f; } pbuf[result_len] = '\0'; retval = pbuf; } else { errno = EVMSERR; vaxc$errno = status; } } /* end switch */ free(myprompt); if (!(flags & RPP_ECHO_ON) && (stdin_is_tty)) { /* * Reenable previous control processing. */ status = LIB$ENABLE_CTRL(&saved_ctrl_mask); if (!$VMS_STATUS_SUCCESS(status)) { errno = EVMSERR; vaxc$errno = status; return NULL; } } return retval; } /* getpassphrase */