/* Program Name : DX.C */ /* Original Author : Chau-Kuang Hung */ /* Date : 7-12-89 */ /* Chau-Kuang Hung (chung@us.oracle.com) */ /* Oracle Corporation */ /* 300 Oracle Parkway */ /* BOX 659304 */ /* Redwood Shores, CA 94065 */ /* */ /* Program Description : */ /* DX is a VAX/VMS utility for displaying files on a VT100 or */ /* upper type terminal. It can be used to delete, edit, or */ /* rename files in the current directory. DX can also create a */ /* hardcopy listing of all the files displayed. */ /* : */ /* References */ /* Files open for Input : */ /* Files open for Output : */ /* Modules Referenced : */ /* */ /* Revision History follows */ /* 04-Jun-1999 JL Modified for CLI and MSG interface */ /* Modified for (weak) error handler */ /* ** .......................................................................... ** ** DISTRIBUTION AND COPYRIGHT: ** ** Copyright (C) 1989-1992 Chau-Kuang Hung ** Copyright 1994-1999 (c) Jérôme Lauret ** ** This program is free software; permission is granted to any ** individual or institution to use, copy, or redistribute this ** software so long as it is not sold for profit, provided this ** copyright notice is retained. ** ** DISCLAIMER: ** ** This software and its documentation are provided "AS IS" and ** without any expressed or implied warranties whatsoever. ** No warranties as to performance, merchantability, or fitness ** for a particular purpose exist. ** ** In no event shall any person or organization of people be ** held responsible for any direct, indirect, consequential ** or inconsequential damages or lost profits. ** ** .......................................................................... **/ #include "global.h" #include "directque.h" #include "dx.h" #include "filer.h" #include "filerque.h" #include "findfile.h" #include "inquire.h" #include #include #include #include #include #include #include #include #include #include /* **** INTERNAL FUNCTION PROTOTYPING *** */ static int DX_initialized(void); static int parse_cli_parameters(void); static int parse_cli_qualifiers(void); static int trnlnm_1(const char *, int *, int *); /* ** FUNCTIONAL DESCRIPTION: ** ** MAIN() is the main driver routine ** **/ main() { /* ** Initialize DX for execution **/ DX_initialized(); /* ** Find all the files in the directory. The status returned from ** the function calls are not checked since the only reason to ** fail is run out of memory, which is very unlikely for the first ** call. **/ find_direct_file(); find_exclude_file( &DX_CURRENT_DIRECTORY.exclude_filelist, DX_CURRENT_DIRECTORY.cur_filter, DX_CURRENT_DIRECTORY.sortby, DX_CURRENT_DIRECTORY.sortorder); find_non_direct_file(); /* ** Process commands until user exits **/ DX_process_loop(); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** Initialization routine that fills the global data ** CNTRL_INFO_BLOCK. Every fields in CNTRL_INFO_BLOCK will be ** assigned a value except DIR_DX, which will be assigned in ** PARSE_CLI_QUALIFIERS(). ** **-- **/ static int DX_initialized() { static unsigned long type_of_terminal; struct SMG$R_ATTRIBUTE_INFO_BLOCK pasteboard_info_table; long int rows, status_rightmost; int i; /* ** Initially, there is only one winodw. ** The window number is 0. **/ cntrl_info_block.windows = 1; cntrl_info_block.cur_win = 0; /* ** Parse command-line parameters. Abort DX if invalid directory ** or file specification. **/ cntrl_info_block.dir_dx[0].cur_dir[0] = EOS; cntrl_info_block.dir_dx[0].par_dir[0] = EOS; if (parse_cli_parameters() == DX__ERROR) { exit(DXM__BADPARSE); } /* ** Set up smg$ environment and verify that the display ** device is valid (must be vt-100 or up). **/ if (smg$create_pasteboard ( &cntrl_info_block.pasteboard_id, $DESCR ("SYS$OUTPUT"), 0, 0, 0, &type_of_terminal) != SS$_NORMAL) { exit(DXM__NANSITERM); } if (type_of_terminal != SMG$K_VTTERMTABLE) { exit(DXM__NANSITERM); } check_OK(smg$get_pasteboard_attributes ( &cntrl_info_block.pasteboard_id, &pasteboard_info_table, &SMG$C_PASTEBOARD_INFO_BLOCK)) if (pasteboard_info_table.SMG$B_DEV_TYPE < TT$_VT100) { exit(DXM__NONVT100CRT); } if (pasteboard_info_table.SMG$R_ROW_OVERLAY.SMG$B_NUM_ROWS < CMDS_RSV_LNS+DIRINFO_RSV_LNS+4) { exit(DXM__PGLEN); } cntrl_info_block.pasteboard_rows = (unsigned short) pasteboard_info_table.SMG$R_ROW_OVERLAY.SMG$B_NUM_ROWS; cntrl_info_block.pasteboard_width = /** Set maximum columns to 80 **/ min (80, pasteboard_info_table.SMG$W_NUM_COLUMNS); if (cntrl_info_block.pasteboard_width < 76) { exit(DXM__PGWID); } /* ** Create a virtual keyboard to accept user input **/ check_OK(smg$create_virtual_keyboard ( &cntrl_info_block.keyboard_id, $DESCR ("SYS$INPUT"), 0, 0, 0)) /* ** Create COMMANDS_DISPLAY to display menus and function keys. ** The virtual display is as large as the pasteboard. **/ check_OK(smg$create_virtual_display ( &cntrl_info_block.pasteboard_rows, &cntrl_info_block.pasteboard_width, &cntrl_info_block.commands_display.id, &SMG$M_TRUNC_ICON, 0, 0)) check_OK(smg$paste_virtual_display ( &cntrl_info_block.commands_display.id, &cntrl_info_block.pasteboard_id, &COMMANDS_PBD_ROW, &COMMANDS_PBD_COLUMN, 0)) cntrl_info_block.commands_display.rows = cntrl_info_block.pasteboard_rows; cntrl_info_block.commands_display.width = cntrl_info_block.pasteboard_width; cntrl_info_block.commands_display.beg_y = COMMANDS_PBD_ROW; cntrl_info_block.commands_display.beg_x = COMMANDS_PBD_COLUMN; /* ** Create STATUS_DISPLAY to show error messages. **/ status_rightmost = cntrl_info_block.pasteboard_width-10; /** Reserve 10 columns for clock **/ check_OK(smg$create_virtual_display ( &STATUS_BOTTOM, &status_rightmost, &cntrl_info_block.status_display.id, &SMG$M_TRUNC_ICON, 0, 0)) cntrl_info_block.status_display.rows = STATUS_BOTTOM; cntrl_info_block.status_display.width = status_rightmost; cntrl_info_block.status_display.beg_y = STATUS_PBD_ROW; cntrl_info_block.status_display.beg_x = STATUS_PBD_COLUMN; /* ** Use default settings for the user preference. They will be ** overwritten by the command-line options or the initial file. **/ use_default("", "", ""); /* ** Define all other settings except for the directory equivalent ** names and directory file id. Use one window initially. **/ /** Create a virtual display to show directory-related information **/ rows = cntrl_info_block.pasteboard_rows-3; check_OK(smg$create_virtual_display ( &rows, &cntrl_info_block.pasteboard_width, &cntrl_info_block.dir_dx[0].dir_info_display.id, &SMG$M_TRUNC_ICON, 0, 0)) check_OK(smg$paste_virtual_display ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &cntrl_info_block.pasteboard_id, &SINGLE_WINDOW_DIR_INFO_PBD_ROW, &SINGLE_WINDOW_DIR_INFO_PBD_COLUMN, 0)) cntrl_info_block.dir_dx[0].dir_info_display.rows = cntrl_info_block.pasteboard_rows-3; cntrl_info_block.dir_dx[0].dir_info_display.width = cntrl_info_block.pasteboard_width; cntrl_info_block.dir_dx[0].dir_info_display.beg_y = SINGLE_WINDOW_DIR_INFO_PBD_ROW; cntrl_info_block.dir_dx[0].dir_info_display.beg_x = SINGLE_WINDOW_DIR_INFO_PBD_COLUMN; cntrl_info_block.dir_dx[0].form = long_form; cntrl_info_block.dir_dx[0].sortby = sortname; cntrl_info_block.dir_dx[0].sortorder = ascending; cntrl_info_block.dir_dx[0].filemode = single; cntrl_info_block.dir_dx[0].direction = advance; cntrl_info_block.dir_dx[0].exitn = 0; cntrl_info_block.dir_dx[0].dir_filelist = NULL; cntrl_info_block.dir_dx[0].non_dir_filelist = NULL; cntrl_info_block.dir_dx[0].exclude_filelist = NULL; cntrl_info_block.dir_dx[0].cur_file = NULL; strcpy(cntrl_info_block.dir_dx[0].search_pattern, "*"); cntrl_info_block.dir_dx[0].tot_files = 0; cntrl_info_block.dir_dx[0].tot_blocks = 0; cntrl_info_block.dir_dx[0].sel_files = 0; cntrl_info_block.dir_dx[0].sel_blocks = 0; cntrl_info_block.dir_dx[0].dpro = 0Xffff; cntrl_info_block.dir_dx[0].subdir = 0; cntrl_info_block.dir_dx[0].cur_filter.date = DX_CREDATE; convert_date_string ( "31-DEC-2857 00:00:00.00", &cntrl_info_block.dir_dx[0].cur_filter.before); convert_date_string ( "17-NOV-1858 00:00:00.00", &cntrl_info_block.dir_dx[0].cur_filter.since); cntrl_info_block.dir_dx[0].cur_filter.maximum = 1073741823; cntrl_info_block.dir_dx[0].cur_filter.minimum = 0; /* ** Parse command-line qualifiers **/ parse_cli_qualifiers(); /* ** Trap broadcast messages **/ check_OK(smg$set_broadcast_trapping ( &cntrl_info_block.pasteboard_id, broadcast_routine, 0)) /* ** Initilaize filer and directory info buffer **/ initialize_filer_cache(); initialize_direct_cache(); /* ** Return normal status **/ return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** PARSE_CLI_PARAMETERS() gets command-line parameters ** from the foreign command. ** **-- **/ static int parse_cli_parameters() { unsigned short int len; char original_cwd[MAXFILESPEC+1]; struct { short buflen; short itemcode; char *buf; short *reslen; } itmlist [] = { { MAXFILESPEC, LNM$_STRING, original_cwd, &len }, { 0, 0, 0, 0 } }; char curdir[MAXFILESPEC+1]; $DESCRIPTOR (curdir_descrip, curdir); char resultant_string[MAXFILESPEC+1]; $DESCRIPTOR(resultant_string_descrip, resultant_string); char lognm[MAXFILESPEC+1]; /** LOG NAME(BEFORE TRANSLATED) **/ $DESCRIPTOR (lognm_descrip, lognm); unsigned long int status; char default_filespec[MAXFILESPEC+1]; char errmsg[MAXFILESPEC+1]; #include "dxcli.h" /* ** Get current working directory (use full vms filespec.) **/ strcpy(lognm, "SYS$DISK"); LENGTH(lognm_descrip) = strlen(lognm); check_OK(sys$trnlnm ( 0, $DESCR ("LNM$FILE_DEV"), &lognm_descrip, 0, itmlist)) strncpy (cntrl_info_block.original_cwd, original_cwd, len); cntrl_info_block.original_cwd[len] = EOS; check_OK(sys$setddir ( 0, &len, &resultant_string_descrip)) resultant_string[len] = EOS; strcat(cntrl_info_block.original_cwd, resultant_string); /** Get command-line string **/ check_OK(lib$get_foreign ( &resultant_string_descrip, 0, &len, 0)) strcpy(default_filespec, "*.*;*"); if (len == 0) { /** DX was invoked by 'RUN' command or a command without parameters **/ sprintf(resultant_string, "%s*.*;*", cntrl_info_block.original_cwd); if (insert_filespec_list( &cntrl_info_block.dir_dx[0].cur_filter.name_filespec_list, default_filespec, resultant_string, errmsg) == DX__ERROR) { lib$signal(DXM__OPENIN,1,default_filespec); lib$signal(DXM__ERRMSG,1,errmsg); exit(SS$_NORMAL); } set_cwd_and_par(default_filespec); } else { /** DX was invoked by a command with at least one qualifiers **/ int count = 0; /* ** Process parameter "P1 (FILE_SPEC)" **/ str$concat(&resultant_string_descrip,&command, &resultant_string_descrip); cli$dcl_parse(&resultant_string_descrip,&DX_CLI); while (cli$get_value( $DESCR("FILE_SPEC"), &resultant_string_descrip, &len) & 1) { resultant_string[len] = EOS; if (insert_filespec_list( &cntrl_info_block.dir_dx[0].cur_filter.name_filespec_list, default_filespec, resultant_string, errmsg) != DX__NORMAL) { lib$signal(DXM__OPENIN,1,default_filespec); lib$signal(DXM__ERRMSG,1,errmsg); exit(SS$_NORMAL); } if (count++ == 0) { set_cwd_and_par(default_filespec); } } } /* ** Set default directory to target directory **/ if (setddir(cntrl_info_block.dir_dx[0].cur_dir, errmsg) == DX__ERROR) { lib$signal(DXM__CLIPAR,1,errmsg); return DX__ERROR; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** PARSE_CLI_QUALIFIERS() gets command-line qualifiers ** from the foreign command. ** **-- **/ static int parse_cli_qualifiers() { char resultant_string[MAXFILESPEC+1]; unsigned short int len; $DESCRIPTOR(resultant_string_descrip, resultant_string); char dat_tim_string[256]; $DESCRIPTOR(dat_tim_string_descrip, dat_tim_string); char initial_file[MAXFILESPEC+1]; char errmsg[256]; unsigned long int status; char default_filespec[MAXFILESPEC+1]; #include "dxcli.h" check_OK(lib$get_foreign ( &resultant_string_descrip, 0, &len, 0)) if (len == 0) /** DX was invoked by 'RUN' command or a foreign **/ { /** without any command-line options **/ if (restore_setting(DEFAULT_STARTUP, "init", errmsg) != DX__NORMAL) { sprintf (initial_file, "SYS$LOGIN:%s", DEFAULT_STARTUP); restore_setting(initial_file, "init", errmsg); } } else { /** Invoked from the foreign command **/ /* ** Process qualifier "INITIAL_FILE" **/ str$concat(&resultant_string_descrip,&command, &resultant_string_descrip); cli$dcl_parse(&resultant_string_descrip,&DX_CLI); status = cli$present($DESCR("INITIAL_FILE")); if (cli$present($DESCR("INITIAL_FILE")) == CLI$_PRESENT) { cli$get_value( $DESCR("INITIAL_FILE"), &resultant_string_descrip, &len); resultant_string[len] = EOS; restore_setting(resultant_string, "init", errmsg); } else if (restore_setting(DEFAULT_STARTUP, "init", errmsg) != DX__NORMAL) { sprintf (initial_file, "SYS$LOGIN:%s", DEFAULT_STARTUP); restore_setting(initial_file, "init", errmsg); } /* ** Process qualifier "EXIT" **/ status = cli$present($DESCR("EXIT")); if (status == CLI$_PRESENT || status == CLI$_LOCPRES) { cntrl_info_block.dir_dx[0].exitn = 1; } /* ** Process qualifier "ASCENDING" **/ status = cli$present($DESCR("ASCENDING")); if (status == CLI$_PRESENT || status == CLI$_LOCPRES || status == CLI$_DEFAULTED) { cntrl_info_block.dir_dx[0].sortorder = ascending; } /* ** Process qualifier "DESCENDING" **/ status = cli$present($DESCR("DESCENDING")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT) { cntrl_info_block.dir_dx[0].sortorder = descending; } /* ** Process qualifier "DETAIL" **/ status = cli$present($DESCR("DETAIL")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT || (status == CLI$_DEFAULTED && !cntrl_info_block.user_pref.use_short_form)) { cntrl_info_block.dir_dx[0].form = long_form; } /* ** Process qualifier "BRIEF" **/ status = cli$present($DESCR("BRIEF")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT) { cntrl_info_block.dir_dx[0].form = short_form; } /* ** Process qualifier "BEFORE" **/ status = cli$present($DESCR("BEFORE")); if (status == CLI$_PRESENT) { cli$get_value( $DESCR("BEFORE"), &resultant_string_descrip, &len); resultant_string[len] = EOS; strcpy(dat_tim_string, resultant_string); convert_date_string ( dat_tim_string, &cntrl_info_block.dir_dx[0].cur_filter.before); } /* ** Process qualifier "SINCE" **/ status = cli$present($DESCR("SINCE")); if (status == CLI$_PRESENT) { cli$get_value( $DESCR("SINCE"), &resultant_string_descrip, &len); resultant_string[len] = EOS; strcpy(dat_tim_string, resultant_string); convert_date_string ( dat_tim_string, &cntrl_info_block.dir_dx[0].cur_filter.since); } /* ** Process qualifier "CREATED" **/ status = cli$present($DESCR("CREATED")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT || (status == CLI$_DEFAULTED && cntrl_info_block.user_pref.display_date != DX_REVDATE && cntrl_info_block.user_pref.display_date != DX_EXPDATE && cntrl_info_block.user_pref.display_date != DX_BAKDATE)) { cntrl_info_block.dir_dx[0].cur_filter.date = DX_CREDATE; } /* ** Process qualifier "MODIFIED" **/ status = cli$present($DESCR("MODIFIED")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT) { cntrl_info_block.dir_dx[0].cur_filter.date = DX_REVDATE; } /* ** Process qualifier "EXPIRED" **/ status = cli$present($DESCR("EXPIRED")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT) { cntrl_info_block.dir_dx[0].cur_filter.date = DX_EXPDATE; } /* ** Process qualifier "BACKUP" **/ status = cli$present($DESCR("BACKUP")); if (status == CLI$_LOCPRES || status == CLI$_PRESENT) { cntrl_info_block.dir_dx[0].cur_filter.date = DX_BAKDATE; } /* ** Process qualifier "SORT_BY" **/ cli$get_value($DESCR("SORT_BY"), &resultant_string_descrip, &len); resultant_string[len] = EOS; if (!strncmp (resultant_string, "NAME", len)) { cntrl_info_block.dir_dx[0].sortby = sortname; } else if (!strncmp (resultant_string, "TYPE", len)) { cntrl_info_block.dir_dx[0].sortby = sorttype; } else if (!strncmp (resultant_string, "SIZE", len)) { cntrl_info_block.dir_dx[0].sortby = sortsize; } else if (!strncmp (resultant_string, "DATE", len)) { switch (cntrl_info_block.dir_dx[0].cur_filter.date) { case DX_CREDATE: cntrl_info_block.dir_dx[0].sortby = sortcredate; break; case DX_REVDATE: cntrl_info_block.dir_dx[0].sortby = sortrevdate; break; case DX_EXPDATE: cntrl_info_block.dir_dx[0].sortby = sortexpdate; break; case DX_BAKDATE: cntrl_info_block.dir_dx[0].sortby = sortbakdate; break; default: break; } } /* ** Process qualifier "MAXIMUM" **/ if (cli$present($DESCR("MAXIMUM")) == CLI$_PRESENT) { cli$get_value( $DESCR("MAXIMUM"), &resultant_string_descrip, &len); resultant_string[len] = EOS; cntrl_info_block.dir_dx[0].cur_filter.maximum = atoi(resultant_string); } /* ** Process qualifier "MINIMUM" **/ if (cli$present($DESCR("MINIMUM")) == CLI$_PRESENT) { cli$get_value( $DESCR("MINIMUM"), &resultant_string_descrip, &len); resultant_string[len] = EOS; cntrl_info_block.dir_dx[0].cur_filter.minimum = atoi(resultant_string); } /* ** Process qualifier "EXCLUDE" **/ if (cli$present($DESCR("EXCLUDE")) == CLI$_PRESENT) { strcpy(default_filespec, "*.*;*"); while (cli$get_value( $DESCR("EXCLUDE"), &resultant_string_descrip, &len) & 1) { resultant_string[len] = EOS; insert_filespec_list( &cntrl_info_block.dir_dx[0].cur_filter.exclude_filespec_list, default_filespec, resultant_string, errmsg); } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int trnlnm(original, logicalQ) const char *original; int *logicalQ; { struct logical_queue_entry_tag *E; int status; static _align (QUADWORD) int workingQ[2]; int allocate_size; workingQ[0] = workingQ[1] = 0; /** Allocate dynamic memory for a queue entry **/ allocate_size = sizeof (struct logical_queue_entry_tag); check_OK(lib$get_vm ( &allocate_size, &E, 0)) /* ** Allocate dynamic memory for the content of a queue entry. ** The size is the string length plus EOS. **/ allocate_size = strlen(original)+1; check_OK(lib$get_vm ( &allocate_size, &E->equivalent_name, 0)) strcpy(E->equivalent_name, original); _INSQTI (E, workingQ); /** Insert the first entry to queue **/ while (_REMQHI (workingQ, &E) != 3) trnlnm_1(E->equivalent_name, workingQ, logicalQ); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int trnlnm_1(original, workingQ, logicalQ) const char *original; int *workingQ; int *logicalQ; { char before[256], after[256], final[256]; char postfix[256]; $DESCRIPTOR (original_dst, original); $DESCRIPTOR (before_dst, before); unsigned long status; int maxindex; int index; short retlen; short dummy; struct { short buflen; short itemcode; char *buf; short *reslen; } itmlist_1 [] = { {sizeof(int), LNM$_MAX_INDEX, &maxindex, &retlen}, {0, 0, 0, 0} }, itmlist_2 [] = { {sizeof (int), LNM$_INDEX, &index, &dummy}, {255, LNM$_STRING, after, &retlen}, {0, 0, 0, 0} }; char *cp, *cp1; int allocate_size; struct logical_queue_entry_tag *E; /* Find a logical name to be translate */ strcpy(before, original); if ((cp = strchr(before, ':')) != 0) *cp = EOS; /* Get max index */ LENGTH(before_dst) = strlen(before); if ((status = sys$trnlnm ( &LNM$M_CASE_BLIND, $DESCR ("LNM$FILE_DEV"), &before_dst, 0, itmlist_1)) != SS$_NORMAL) { /** No more translation **/ if ((cp = strchr(original, '[')) != 0) { /** Remove all '[' except the first one **/ cp++; while ((cp1 = strchr(cp, '[')) != 0) memmove (cp1-1, cp1+1, strlen(cp1+1)+1); } allocate_size = sizeof (struct logical_queue_entry_tag); check_OK(lib$get_vm ( &allocate_size, &E, 0)) E->equivalent_name = original; _INSQTI (E, logicalQ); return DX__NORMAL; } for (index = 0; index <= maxindex; index++) { /* Find a logical name to be translate */ strcpy(before, original); if ((cp = strchr(before, ':')) == 0) { postfix[0] = EOS; } else { strcpy(postfix, cp); *cp = EOS; } LENGTH(before_dst) = strlen(before); /* Get i-th equivalent string */ sys$trnlnm ( &LNM$M_CASE_BLIND, $DESCR ("LNM$FILE_DEV"), &before_dst, 0, itmlist_2); after[retlen] = EOS; /* Post to result */ if ((cp = strchr(after, ':')) == 0) sprintf(final, "%s%s", after, postfix); else if (postfix[0] == ':') sprintf(final, "%s%s", after, postfix+1); else sprintf(final, "%s%s", after, postfix); allocate_size = sizeof (struct logical_queue_entry_tag); check_OK(lib$get_vm ( &allocate_size, &E, 0)) allocate_size = strlen(final)+1; check_OK(lib$get_vm ( &allocate_size, &E->equivalent_name, 0)) strcpy(E->equivalent_name, final); _INSQTI (E, workingQ); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int insert_dids(struct w_dids_tag **l,char *s, unsigned short int d[3], unsigned short int c) { struct w_dids_tag *m; int allocate_size; if (*l != NULL) { insert_dids(&((*l)->next), s, d, c); } else { allocate_size = sizeof (struct w_dids_tag); check_OK(lib$get_vm ( &allocate_size, &m, 0)) strcpy(m->equivalent_name, s); m->did[0] = d[0]; m->did[1] = d[1]; m->did[2] = d[2]; m->chan = c; m->next = (struct w_dids_tag *) NULL; *l = m; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int set_cwd_and_par(s) char *s; { static unsigned long context; size_t len; char wild[MAXFILESPEC+1]; $DESCRIPTOR (wild_descrip, wild); char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); char *cp; /* ** Set current woking directory **/ len = strcspn (s, "]")+1; strncpy(DX_CURRENT_DIRECTORY.cur_dir, s, len); DX_CURRENT_DIRECTORY.cur_dir[len] = EOS; /* ** Set parent directory **/ DX_CURRENT_DIRECTORY.par_dir[0] = EOS; strcpy(wild, DX_CURRENT_DIRECTORY.cur_dir); wild[strlen(wild)-1] = EOS; strcat(wild, ".-]*.*;*"); LENGTH(wild_descrip) = strlen(wild); if (lib$find_file ( &wild_descrip, &filespec_descrip, &context, 0, 0, 0, 0) & 1) { if ((cp = strchr(filespec, ']')) != NULL) { *(cp+1) = EOS; strcpy(DX_CURRENT_DIRECTORY.par_dir, filespec); } } lib$find_file_end ( &context); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ unsigned short get_chan(nam) char *nam; { struct dsc$descriptor_s rslbuf = {strlen(nam), DSC$K_DTYPE_T, DSC$K_CLASS_S, nam}; unsigned short chan; check_OK (sys$assign( &rslbuf, &chan, 0, 0)) return chan; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int insert_filespec_list(l, dna, s, errmsg) struct filespec_list_tag **l; char *dna; char *s; char *errmsg; { static _align (QUADWORD) int logicalQ[2]; static unsigned long context; struct filespec_list_tag temp_entry; char dev_dir[MAXFILESPEC+1]; char expand_name[NAM$C_MAXRSS]; struct logical_queue_entry_tag *E; unsigned long int status; struct FAB fab; struct NAM nam; char fab_dna[MAXFILESPEC+1]; int number_of_bytes; char wild[MAXFILESPEC+1]; $DESCRIPTOR (wild_descrip, wild); char devname[MAXFILESPEC+1]; char *cp; char filespec[MAXFILESPEC+1]; $DESCRIPTOR (filespec_descrip, filespec); unsigned short int len; char errmsg1[MAXFILESPEC+1]; $DESCRIPTOR (errmsg1_descrip, errmsg1); logicalQ[0] = logicalQ[1] = 0; /** Initialize FAB and NAM blocks **/ fab = cc$rms_fab; nam = cc$rms_nam; nam.nam$l_esa = &expand_name; nam.nam$b_ess = NAM$C_MAXRSS; /** Get directory fid, name, and equivalent name **/ fab.fab$l_fna = s; fab.fab$b_fns = strlen(s); strcpy(fab_dna, dna); fab.fab$l_dna = fab_dna; fab.fab$b_dns = strlen(fab_dna); fab.fab$l_nam = &nam; status = sys$parse(&fab, 0, 0); if (!(status & 1)) { lib$sys_getmsg ( &status, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); strcpy(dna, s); return DX__ERROR; } /* ** Is this directory accessible? **/ strncpy(wild, expand_name, nam.nam$b_esl); wild[nam.nam$b_esl] = EOS; LENGTH(wild_descrip) = strlen(wild); status = lib$find_file ( &wild_descrip, &filespec_descrip, &context, 0, 0, 0, 0); lib$find_file_end ( &context); if (status != RMS$_FNF && !(status & 1)) { lib$sys_getmsg ( &status, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); strcpy (dna, wild); return DX__ERROR; } strncpy( dna, nam.nam$l_dev, nam.nam$b_dev+nam.nam$b_dir+nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver); dna[nam.nam$b_dev+nam.nam$b_dir+nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver] = EOS; temp_entry.w_dids = NULL; strncpy ( temp_entry.name, nam.nam$l_name, nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver); temp_entry.name[nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver] = EOS; strncpy (dev_dir, nam.nam$l_dev, nam.nam$b_dev+nam.nam$b_dir); dev_dir[nam.nam$b_dev+nam.nam$b_dir] = EOS; /* ** Translate current directory logical name to equivalent name(s). ** The directory may contains more than one physical directories. **/ trnlnm(dev_dir, logicalQ); while (_REMQHI (logicalQ, &E) != 3) { number_of_bytes = strlen(E->equivalent_name)+1; if ((cp = strstr (E->equivalent_name, ".000000]")) != NULL) { *cp++ = ']'; *cp = EOS; } fab.fab$l_fna = E->equivalent_name; fab.fab$b_fns = strlen(E->equivalent_name); fab.fab$l_nam = &nam; status = sys$parse(&fab, 0, 0); if (!(status & 1)) { lib$sys_getmsg ( &status, &len, &errmsg1_descrip, 0, 0); errmsg1[len] = EOS; strcpy(errmsg, errmsg1); strcpy(dna, E->equivalent_name); return DX__ERROR; } /* ** Get an i/o channel for each physical device **/ strcpy(devname, E->equivalent_name); cp = strchr(devname, ':'); *++cp = EOS; insert_dids ( &temp_entry.w_dids, E->equivalent_name, nam.nam$w_did, get_chan(devname)); check_OK(lib$free_vm ( &number_of_bytes, &E->equivalent_name, 0)) } insert_filespec_list$1(l, temp_entry); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int insert_filespec_list$1(l, e) struct filespec_list_tag **l; struct filespec_list_tag e; { struct filespec_list_tag *p; int allocate_size; if (*l != (struct filespec_list_tag *)NULL) { insert_filespec_list$1(&((*l)->next), e); } else { allocate_size = sizeof (struct filespec_list_tag); check_OK(lib$get_vm ( &allocate_size, &p, 0)) strcpy(p->name, e.name); p->w_dids = e.w_dids; p->next = (struct filespec_list_tag *)NULL; *l = p; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int broadcast_routine() { static unsigned short word_terminator_code; unsigned long status; char message[BROADMSGLENG+1]; $DESCRIPTOR (message_descrip, message); unsigned short message_length; unsigned short message_type; unsigned long prev_display_id, display_id; long int start_row, start_column, col; char *prompt = "Press RETURN to continue ..."; $DESCRIPTOR (prompt_descrip, prompt); unsigned long int temp_keyboard_id; char resultant[512]; $DESCRIPTOR (resultant_descrip, resultant); int i; /* ** Do not use 'check' to verify the return status ** (in case of user disables broadcast message) **/ status = smg$get_broadcast_message ( &cntrl_info_block.pasteboard_id, &message_descrip, &message_length, &message_type); if (status == SS$_NORMAL) { message[message_length] = EOS; for (i = 0; i < message_length && !isprint ((int) message[i]); i++) { ; } POINTER (message_descrip) += i; LENGTH(message_descrip) = message_length - i; check_OK(smg$find_cursor_display ( &cntrl_info_block.pasteboard_id, &prev_display_id, 0, 0)) check_OK(smg$return_cursor_pos ( &prev_display_id, &start_row, &start_column)) check_OK(smg$create_virtual_display ( &cntrl_info_block.pasteboard_rows, &cntrl_info_block.pasteboard_width, &display_id, &SMG$M_DISPLAY_CONTROLS, 0, 0)) check_OK(smg$paste_virtual_display ( &display_id, &cntrl_info_block.pasteboard_id, &1, &1, 0)) smg$put_chars ( &display_id, &message_descrip, 0, 0, 0, &SMG$M_BOLD, 0, 0); col = cntrl_info_block.pasteboard_width - strlen(prompt); LENGTH(prompt_descrip) = strlen(prompt); check_OK(smg$put_chars ( &display_id, &prompt_descrip, &cntrl_info_block.pasteboard_rows, &col, 0, &SMG$M_BOLD, 0, 0)) check_OK(smg$cancel_input ( &cntrl_info_block.keyboard_id)) gets (resultant); check_OK(smg$erase_display ( &display_id, 0, 0, 0, 0)) check_OK(smg$delete_virtual_display ( &display_id)) check_OK(smg$set_cursor_abs ( &prev_display_id, &start_row, &start_column)) } return DX__NORMAL; }