/* Program Name : FILER.C */ /* Original Author : C. K. Hung */ /* Date : 7-12-89 */ /* Program Description : */ /* This is the main driver of the file-management portion of the */ /* DX utility. It accepts user command to perform functions such */ /* as delete, edit, or rename files in the current directory. */ /* : */ /* Revision History follows */ /* 03-Jun-1999 Fixed bug with PF1 */ /* Weak /EXIT support */ #include "global.h" #include "direct.h" #include "diff.h" #include "dx.h" #include "endecode.h" #include "filer.h" #include "filerapp.h" #include "filercpy.h" #include "filerdec.h" #include "filerdel.h" #include "filerdif.h" #include "fileredt.h" #include "filerenc.h" #include "filerfnd.h" #include "filerkpd.h" #include "filerlau.h" #include "filerpro.h" #include "filerprt.h" #include "filerpur.h" #include "filerren.h" #include "filersta.h" #include "filertyp.h" #include "filercus.h" #include "filerexe.h" #include "filerflt.h" #include "fileropt.h" #include "filersrt.h" #include "filerwin.h" #include "filerque.h" #include "findfile.h" #include "inquire.h" #include #include #include #include /* ** GLOBAL DECLARATIONS **/ struct menutype filer_menu[] = { { " Window ", GEN_CMDS_ROW, 1, { "Split window", "Delete window", "One window", MENU_SEPARATOR, "Next window", "Previous window", MENU_SEPARATOR, "eXit", NULL }, { filer_split_win, filer_delete_win, filer_one_win, NULL, filer_next_win, filer_prev_win, NULL, filer_exitset }, }, { " Action ", GEN_CMDS_ROW, 9, { "Type", "Edit", "Delete", "purGe", "Rename...", "Copy...", "Append...", "Set protection...", "Print...", "Show", "Find...", "Run...", "Compare...", "pacK...", "Unpack...", NULL }, { filer_type, filer_edt, filer_delete, filer_purge, filer_rename, filer_copy, filer_append, filer_protection, filer_print, filer_status, filer_find, filer_launch, filer_diff, filer_encode, filer_decode }, }, { " Execute ", GEN_CMDS_ROW, 17, { "Command", "VMS Gateway", NULL }, { filer_vms_command, filer_vms_gateway }, }, { " Sort ", GEN_CMDS_ROW, 26, { "by Name...", "by Type...", "by Date...", "by Size...", "by Marked...", NULL }, { filer_sort_name, filer_sort_type, filer_sort_date, filer_sort_size, filer_sort_mark } }, { " Filter ", GEN_CMDS_ROW, 32, { "Name...", "Exclude...", "Since...", "Before...", "maXimum...", "Minimum...", NULL }, { filer_filter_name, filer_filter_exclude, filer_filter_since, filer_filter_before, filer_filter_maximum, filer_filter_minimum }, }, { " Option ", GEN_CMDS_ROW, 40, { "Direct tree", "Update", "Mkdir...", "show Buffer", "Write...", "Goto...", MENU_SEPARATOR, "Short form", "Long form", MENU_SEPARATOR, "Include all", "Exclude all", "Re-include all", MENU_SEPARATOR, "About DX", NULL }, { filer_direct, filer_update, filer_mkdir, filer_show_buffer, filer_write, filer_goto, NULL, filer_short_form, filer_long_form, NULL, filer_mark_all, filer_unmark_all, filer_remark_all, NULL, filer_about }, }, { " Customize ", GEN_CMDS_ROW, 48, { "Editor...", "Display with date...", "Type file...", "Auto update...", "Delete confirm...", "Purge confirm...", "Show clock...", "Flash clock colon...", MENU_SEPARATOR, "Save settings...", "Restore settings...", "Use defaults", NULL }, { custom_editor, custom_display_date, custom_type, custom_auto_update, custom_delete, custom_purge, custom_display_clock, custom_update_in_second, NULL, custom_save_setting, custom_restore_setting, custom_use_default }, }, NULL }; /* ** ** INTERNAL FUNCTION PROTOTYPING ** **/ static int filter_alarm_working$1(); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int DX_process_loop() { int number_of_items; char *c1, *c2; struct menutype *mp; char valid_cmdstr[MAXCOMMANDSITEMNUM+1]; long int row, col; unsigned short keystroke; unsigned long status; int choice_no; char keyname[15]; $DESCRIPTOR (keyname_descrip, keyname); char errmsg[MAXFILESPEC+1]; /** Error message buf **/ div_t div_p; int all_dirs; int pages; int test; char pages_str[10]; /* ** Get valid commands string **/ number_of_items = 0; c1 = valid_cmdstr; for (mp = filer_menu; mp->itmstr; mp++) for (c2 = mp->itmstr; *c2; c2++) if (isupper (*c2)) { *c1++ = *c2; number_of_items++; break; } *c1 = EOS; /* ** Write status and command lines **/ if(!cntrl_info_block.dir_dx[cntrl_info_block.cur_win].exitn){ put_general_cmds(filer_menu); if (cntrl_info_block.user_pref.display_clock) write_time(cntrl_info_block.commands_display.id); put_filer_pfs(FILER_PFS, cntrl_info_block.commands_display.id); } /* ** Compute the position of each file **/ DX_CURRENT_DIRECTORY.dir_filelist->beg_y = DX_CURRENT_DIRECTORY.dir_filelist->beg_x = 1; row = col = 1; compute_filer_begin_xy ( DX_CURRENT_DIRECTORY.dir_filelist, &row, &col, cntrl_info_block.cur_win); DX_CURRENT_DIRECTORY.non_dir_filelist->beg_y = DX_CURRENT_DIRECTORY.dir_filelist->backward->beg_y; DX_CURRENT_DIRECTORY.non_dir_filelist->beg_x = DX_CURRENT_DIRECTORY.dir_filelist->backward->beg_x; compute_filer_begin_xy ( DX_CURRENT_DIRECTORY.non_dir_filelist, &row, &col, cntrl_info_block.cur_win); /* ** Create FILER virtual display **/ DX_CURRENT_DIRECTORY.filer_display.view_rows = cntrl_info_block.pasteboard_rows-CMDS_RSV_LNS-DIRINFO_RSV_LNS; DX_CURRENT_DIRECTORY.filer_display.view_width = cntrl_info_block.pasteboard_width; DX_CURRENT_DIRECTORY.filer_display.view_beg_y = 1; DX_CURRENT_DIRECTORY.filer_display.view_beg_x = 1; DX_CURRENT_DIRECTORY.filer_display.rows = max (DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y, DX_CURRENT_DIRECTORY.filer_display.view_rows); DX_CURRENT_DIRECTORY.filer_display.width = cntrl_info_block.pasteboard_width; DX_CURRENT_DIRECTORY.filer_display.beg_y = FILER_PBD_ROW; DX_CURRENT_DIRECTORY.filer_display.beg_x = FILER_PBD_COLUMN; check_OK(smg$create_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.rows, &DX_CURRENT_DIRECTORY.filer_display.width, &DX_CURRENT_DIRECTORY.filer_display.id, 0, 0, 0)) check_OK(smg$create_viewport ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.view_beg_y, &DX_CURRENT_DIRECTORY.filer_display.view_beg_x, &DX_CURRENT_DIRECTORY.filer_display.view_rows, &DX_CURRENT_DIRECTORY.filer_display.view_width)) /* ** Set current file pointer. Make sure at least one file exists ** in the directory file list **/ DX_CURRENT_DIRECTORY.cur_file = (DX_CURRENT_DIRECTORY.dir_filelist->forward != DX_CURRENT_DIRECTORY.dir_filelist? DX_CURRENT_DIRECTORY.dir_filelist->forward : DX_CURRENT_DIRECTORY.non_dir_filelist->forward); /* ** Write directory title and statistics **/ if(!cntrl_info_block.dir_dx[cntrl_info_block.cur_win].exitn){ put_filer_title(cntrl_info_block.cur_win); put_filer_stat(cntrl_info_block.cur_win); /* ** Write directory and page info **/ /* div_p = div (cntrl_info_block.dir_dx[0].non_dir_filelist->backward->beg_y, cntrl_info_block.dir_dx[0].filer_display.view_rows); pages = (div_p.rem == 0? div_p.quot : div_p.quot+1); all_dirs = (strcmp(cntrl_info_block.dir_dx[0].dir_filelist->forward->fn, "[-]")? cntrl_info_block.dir_dx[0].subdir : cntrl_info_block.dir_dx[0].subdir+1); sprintf(pages_str, "Total of %d %s, %d %s read", all_dirs, (all_dirs > 1? "directories" : "directory"), pages, (pages > 1? "pages" : "page")); signal_err(pages_str, silence); */ } /* ** Write all the files to screen **/ write_to_filer( cntrl_info_block.dir_dx[cntrl_info_block.cur_win].dir_filelist); write_to_filer( cntrl_info_block.dir_dx[cntrl_info_block.cur_win].non_dir_filelist); if(!cntrl_info_block.dir_dx[cntrl_info_block.cur_win].exitn) highlight_filer_current_file(); check_OK(smg$paste_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &cntrl_info_block.pasteboard_id, &DX_CURRENT_DIRECTORY.filer_display.beg_y, &DX_CURRENT_DIRECTORY.filer_display.beg_x, 0)) /* Exit immediatly. Will do better later */ if(cntrl_info_block.dir_dx[cntrl_info_block.cur_win].exitn){ setddir(cntrl_info_block.original_cwd, errmsg); check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) exit(SS$_NORMAL); } /* ** Loop until exited by user **/ while (1) { /* ** Read next command. Clear error message line if any. **/ int timeout = cntrl_info_block.user_pref.update_in_second? 1 : 60; do { status = smg$read_keystroke ( &cntrl_info_block.keyboard_id, &keystroke, 0, &timeout, 0, 0, 0); if (cntrl_info_block.user_pref.display_clock) write_time(cntrl_info_block.commands_display.id); } while (status == SS$_TIMEOUT || keystroke == SMG$K_TRM_CANCELLED); check_OK(smg$get_pasting_info ( &cntrl_info_block.status_display.id, &cntrl_info_block.pasteboard_id, &status, 0, 0)) if (status == SMG$M_DISPLAY_PASTED) check_OK(smg$unpaste_virtual_display ( &cntrl_info_block.status_display.id, &cntrl_info_block.pasteboard_id)) /* ** Do job according to key pressed **/ /* PF1 = 256 will crash DX on Alpha */ if( keystroke != 256){ test = isalnum(keystroke) && (c1 = strchr(valid_cmdstr, (char) _toupper(keystroke))) != NULL; } else { test = 0; } if (test){ choice_no = (int) (c1-valid_cmdstr); keystroke = navigator( filer_menu, &choice_no, number_of_items); } else { switch (keystroke) { /** Exit without changing directory **/ case SMG$K_TRM_KP0: setddir(cntrl_info_block.original_cwd, errmsg); /** Scroll screen up 1 line **/ check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) fprintf(stderr, "\033E"); /* ** NEVER RETURN!!! **/ exit(SS$_NORMAL); case SMG$K_TRM_CTRLZ: setddir(cntrl_info_block.original_cwd, errmsg); check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) fprintf(stderr, "\033E"); exit(SS$_NORMAL); case SMG$K_TRM_CTRLE: setddir(cntrl_info_block.original_cwd, errmsg); check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &cntrl_info_block.pasteboard_rows, &1)) fprintf(stderr, "\033E"); exit(SS$_NORMAL); case SMG$K_TRM_CTRLW: /** Refresh screen **/ check_OK(smg$repaint_screen ( &cntrl_info_block.pasteboard_id)) break; case SMG$K_TRM_HT: /** Next window **/ filer_next_win(); break; /** Help command **/ case SMG$K_TRM_KP1: filer_help("DX"); break; case SMG$K_TRM_HELP: filer_help("DX"); break; case SMG$K_TRM_KP2: /** Forward/backward switch **/ if (DX_CURRENT_DIRECTORY.direction == advance) { DX_CURRENT_DIRECTORY.direction = backup; } else { DX_CURRENT_DIRECTORY.direction = advance; } put_filer_title(cntrl_info_block.cur_win); break; case SMG$K_TRM_KP3: /** Find first command **/ filer_find_first(); break; case SMG$K_TRM_KP4: /** Find next command **/ filer_find_next(); break; case SMG$K_TRM_KP5: /** Move to top **/ unhighlight_filer_current_file(); filer_top(); break; case SMG$K_TRM_KP6: /** Move to bottom **/ unhighlight_filer_current_file(); filer_bottom(); break; case SMG$K_TRM_KP7: /** Include/exclude switch **/ if (DX_CURRENT_FILE->state != ready) filer_mark(DX_CURRENT_FILE, 0); else filer_unmark(DX_CURRENT_FILE, 0); break; /** Page up/down **/ case SMG$K_TRM_KP8: unhighlight_filer_current_file(); if (cntrl_info_block.dir_dx[cntrl_info_block.cur_win].direction == advance) filer_page_down(); else filer_page_up(); break; case SMG$K_TRM_E5: unhighlight_filer_current_file(); filer_page_up(); break; case SMG$K_TRM_E6: unhighlight_filer_current_file(); filer_page_down(); break; case SMG$K_TRM_KP9: /** Single/multiple switch **/ if (DX_CURRENT_DIRECTORY.filemode == single) { /** Enter MULTIPLE mode **/ DX_CURRENT_DIRECTORY.filemode = multiple; } else { /** Single mode **/ DX_CURRENT_DIRECTORY.filemode = single; } put_filer_title(cntrl_info_block.cur_win); break; case SMG$K_TRM_UP: /** Move up **/ unhighlight_filer_current_file(); filer_up(); break; case SMG$K_TRM_DOWN: /** Move down **/ unhighlight_filer_current_file(); filer_down(); break; case SMG$K_TRM_LEFT: /** Move left **/ unhighlight_filer_current_file(); filer_left(); break; case SMG$K_TRM_RIGHT: /** Move right **/ unhighlight_filer_current_file(); filer_right(); break; case SMG$K_TRM_CR: /** Change directory **/ if (DX_CURRENT_FILE->fn[strlen(DX_CURRENT_FILE->fn)-1] != ']') { check_OK(smg$ring_bell ( &DX_CURRENT_DIRECTORY.filer_display.id, 0)) } else { char buf[MAXFILESPEC+1]; char *cp; int (*cstat)(); /* ** Output 'working...' message if total processing time ** is longer than 3 seconds. Needs to disable broadcast ** message first to avoid interference. **/ #ifndef DEBUG check_OK(smg$disable_broadcast_trapping ( &cntrl_info_block.pasteboard_id)) cstat = signal(SIGALRM, filter_alarm_working); alarm(1); #endif find_full_path_name( DX_CURRENT_FILE->fn, buf, cntrl_info_block.cur_win); if ((cp = strchr(buf, ']')) != NULL) { *cp = '.'; } cp = strrchr(buf, '.'); *cp++ = ']'; *cp = EOS; if (filer_filter$1(buf, "Name", errmsg) == DX__ERROR) { signal_err(errmsg, bell); } else { check_OK(smg$erase_chars ( &cntrl_info_block.commands_display.id, &10, &2, &1)) } /* ** Set the signal back to system default **/ #ifndef DEBUG alarm(0); signal(SIGALRM, cstat); check_OK(smg$set_broadcast_trapping ( &cntrl_info_block.pasteboard_id, broadcast_routine, 0)) #endif } break; default: /** Key with no definition **/ memset (keyname, ' ', 15); smg$keycode_to_name ( &keystroke, &keyname_descrip); keyname[strcspn (keyname, " ")] = EOS; sprintf (errmsg, "Key '%s' currently has no definition", keyname); signal_err(errmsg, bell); } } /** switch (keystroke) **/ /** Reposition the cursor **/ highlight_filer_current_file(); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int put_general_cmds(m) struct menutype *m; { char line[81]; $DESCRIPTOR (line_descrip, line); char str1[2]; $DESCRIPTOR(str1_descrip, str1); struct menutype *p; int len; /* register long int i, j; */ long int i,j; check_OK(smg$begin_display_update ( &cntrl_info_block.commands_display.id)) memset (line, ' ', cntrl_info_block.pasteboard_width); LENGTH(line_descrip) = cntrl_info_block.pasteboard_width; check_OK(smg$put_chars ( &cntrl_info_block.commands_display.id, &line_descrip, &GEN_CMDS_ROW, &GEN_CMDS_COLUMN, 0, 0, 0, 0)) LENGTH(str1_descrip) = 1; for (p = m; p->itmstr; p++) { len = strlen(p->itmstr); for (i = 0, j = p->start_col; i < len; i++, j++) { str1[0] = *(p->itmstr+i); if (! isupper(str1[0])) { check_OK(smg$put_chars ( &cntrl_info_block.commands_display.id, &str1_descrip, &GEN_CMDS_ROW, &j, 0, 0, 0, 0)) } else { check_OK(smg$put_chars ( &cntrl_info_block.commands_display.id, &str1_descrip, &GEN_CMDS_ROW, &j, 0, &SMG$M_UNDERLINE, &SMG$M_BOLD, 0)) } } } check_OK(smg$end_display_update ( &cntrl_info_block.commands_display.id)) return DX__NORMAL; } /* **++ ** ** tbs ** **-- **/ int write_time(time_display_id) unsigned long int time_display_id; { #define TIME_STR_LENGTH 23 unsigned long int old_display_id; time_t time_val; struct tm *tp; char time_str[TIME_STR_LENGTH]; $DESCRIPTOR (time_descrip, time_str); long int start_row, start_column; long int time_column; char hour_str[3]; int tm_hour; smg$find_cursor_display ( &cntrl_info_block.pasteboard_id, &old_display_id, 0, 0); smg$return_cursor_pos ( &old_display_id, &start_row, &start_column); /* ** Get time information **/ lib$date_time(&time_descrip); POINTER(time_descrip) = time_str+12; LENGTH(time_descrip) = 8; if (cntrl_info_block.user_pref.update_in_second && strchr("13579", *(time_str+19))) { *(time_str+14) = ' '; } if ((tm_hour = atoi(time_str+12)) < 12) { strcpy(time_str+17, " AM"); } else { strcpy(time_str+17, " PM"); if (tm_hour > 12) { sprintf(hour_str, "%02.2d", tm_hour-12); memcpy(time_str+12, hour_str, 2); } } /* ** Write the time information onto the upper right corner ** of the screen **/ smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id); time_column = cntrl_info_block.pasteboard_width-8; smg$put_chars ( &time_display_id, &time_descrip, &TIME_ROW, &time_column, 0, 0, 0, 0); smg$set_cursor_abs ( &old_display_id, &start_row, &start_column); smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id); return DX__NORMAL; } /* **++ ** ** tbs ** **-- **/ int clear_time() { unsigned long int old_display_id; long int start_row, start_column; $DESCRIPTOR (blank_time, " "); long int time_column; check_OK(smg$find_cursor_display ( &cntrl_info_block.pasteboard_id, &old_display_id, 0, 0)) check_OK(smg$return_cursor_pos ( &old_display_id, &start_row, &start_column)) /* ** Clear time display line **/ check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) time_column = cntrl_info_block.pasteboard_width-8; check_OK(smg$put_chars ( &cntrl_info_block.commands_display.id, &blank_time, &TIME_ROW, &time_column, 0, 0, 0, 0)) check_OK(smg$set_cursor_abs ( &old_display_id, &start_row, &start_column)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int put_filer_pfs(pfs_def, display_id) char *pfs_def; unsigned long int display_id; { char filer_pfstr[81]; $DESCRIPTOR(filer_pfstr_descrip, filer_pfstr); char str2[3]; $DESCRIPTOR(str2_descrip, str2); long int i, j, f; check_OK(smg$begin_display_update ( &display_id)) strcpy(filer_pfstr, pfs_def); LENGTH(filer_pfstr_descrip) = strlen(filer_pfstr); check_OK(smg$put_chars ( &display_id, &filer_pfstr_descrip, &cntrl_info_block.pasteboard_rows, &1, &SMG$M_ERASE_TO_EOL, &SMG$M_REVERSE, 0, 0)) strcpy(str2, "1"); LENGTH(str2_descrip) = 1; check_OK(smg$put_chars ( &display_id, &str2_descrip, &cntrl_info_block.pasteboard_rows, &1, 0, &SMG$M_BOLD, 0, 0)) LENGTH(str2_descrip) = 2; for (f = 2, i = 7; f <= 9; i += 8, f++) { sprintf(str2, "%2.2d", f); j = i+1; check_OK(smg$put_chars ( &display_id, &str2_descrip, &cntrl_info_block.pasteboard_rows, &j, 0, &SMG$M_BOLD, 0, 0)) } strcpy(str2, " 0"); LENGTH(str2_descrip) = strlen(str2); j = i + 1; check_OK(smg$put_chars ( &display_id, &str2_descrip, &cntrl_info_block.pasteboard_rows, &j, 0, &SMG$M_BOLD, 0, 0)) check_OK(smg$set_cursor_abs ( &display_id, &cntrl_info_block.pasteboard_rows, &cntrl_info_block.pasteboard_width)) check_OK(smg$end_display_update ( &display_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int compute_filer_begin_xy( struct fil_dx_tag *l, long int *rowp, long int *colp, unsigned short int win) { struct fil_dx_tag *p; int len; for (p = l->forward; p != l; p = p->forward) { if (cntrl_info_block.dir_dx[win].form == long_form) { p->beg_y = *rowp; p->beg_x = *colp; (*rowp)++; } else { len = strlen(p->fn); if (len <= FILER_COLUMN_WIDTH-2) { p->beg_y = *rowp; p->beg_x = *colp; *colp += FILER_COLUMN_WIDTH; } else if (len <= 2*FILER_COLUMN_WIDTH-2) { if (*colp > 2*FILER_COLUMN_WIDTH+1) { (*rowp)++; *colp = 1; } p->beg_y = *rowp; p->beg_x = *colp; *colp += 2*FILER_COLUMN_WIDTH; } else if (len <= 3*FILER_COLUMN_WIDTH-2) { if (*colp > FILER_COLUMN_WIDTH+1) { (*rowp)++; *colp = 1; } p->beg_y = *rowp; p->beg_x = *colp; *colp += 3*FILER_COLUMN_WIDTH; } else { if (*colp > 1) { (*rowp)++; *colp = 1; } p->beg_y = *rowp; p->beg_x = *colp; *colp += 4*FILER_COLUMN_WIDTH; } if (*colp > 4*FILER_COLUMN_WIDTH) { (*rowp)++; *colp = 1; } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** WRITE_TO_FILER() writes all the files to current FILER display ** **-- **/ int write_to_filer(MARKER) struct fil_dx_tag *MARKER; { struct fil_dx_tag *p; char str[81]; $DESCRIPTOR(str_descrip, str); for (p = MARKER->forward; p != MARKER; p = p->forward) { format_filer_entry(p, str, cntrl_info_block.cur_win); POINTER(str_descrip) = str; if (MARKER == DX_CURRENT_DIRECTORY.non_dir_filelist) { /** non-direcotry file **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &p->beg_y, &p->beg_x, 0, 0, 0, 0)) } else if (DX_CURRENT_DIRECTORY.form == short_form) { /** Directory file with short form **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &p->beg_y, &p->beg_x, 0, &SMG$M_BOLD, 0, 0)) } else { /** Directory file with long form **/ char *cp; LENGTH(str_descrip) = 1; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &p->beg_y, &1, 0, 0, 0, 0)) if (!strcmp(p->fn, "[-]")) { check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, $DESCR ("[-]"), &p->beg_y, &2, 0, &SMG$M_BOLD, 0, 0)) } else { if (strlen(p->fn) <= 30) { POINTER(str_descrip) = p->fn; LENGTH(str_descrip) = strlen(p->fn); } else { POINTER(str_descrip) = str+1; LENGTH(str_descrip) = 30; } check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &p->beg_y, &2, 0, &SMG$M_BOLD, 0, 0)) cp = str+32; POINTER(str_descrip) = cp; LENGTH(str_descrip) = strlen(cp); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &p->beg_y, &33, 0, 0, 0, 0)) } } check_OK(smg$set_cursor_abs ( &DX_CURRENT_DIRECTORY.filer_display.id, &p->beg_y, &p->beg_x)) } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FORMAT_FILER_ENTRY () format a string for FILER display ** **-- **/ void format_filer_entry(struct fil_dx_tag *p,char *str, unsigned short int win) { char spro[5], /** PROTECTION CODES **/ opro[5], gpro[5], wpro[5]; unsigned short int timbuf[7]; unsigned long day_number; char ch; char *cp; DATE_TIME date_time, resultant_time, today, yesterday, delta_time, weekday; int g; char wday[9]; str[0] = EOS; switch (p->state) { case ready: ch = '*'; break; case executed: ch = '+'; break; case waiting: default: ch = ' '; break; } if (cntrl_info_block.dir_dx[win].form == short_form) { /** Display in short form **/ sprintf (str, "%c%s", ch, p->fn); } else if (!strcmp(p->fn, "[-]")) { /** Parent directory placeholder **/ strcpy(str, " [-]"); } else { /** Directory file or non-directory file **/ if (p->fpro == 0Xffff) { /** Insufficient privilege **/ if (strlen(p->fn) <= 30) sprintf(str, "%c%-30.30s insufficient privilege for read operation", ch, p->fn); else sprintf(str, "%c%-29.29s~ insufficient privilege for read operation", ch, p->fn); } else if (p->fpro == 0Xfffe) { /** No such file **/ if (strlen(p->fn) <= 30) sprintf(str, "%c%-30.30s no such file", ch, p->fn); else sprintf(str, "%c%-29.29s~ no such file", ch, p->fn); } else { /** Normal file **/ /** Processing file protection **/ getpro(p->fpro, spro, opro, gpro, wpro); /** Processing file creation date or revision date **/ switch (cntrl_info_block.dir_dx[win].cur_filter.date) { case DX_CREDATE: memcpy (&date_time, &p->cdat, sizeof (DATE_TIME)); break; case DX_REVDATE: memcpy (&date_time, &p->rdat, sizeof (DATE_TIME)); break; case DX_EXPDATE: memcpy (&date_time, &p->edat, sizeof (DATE_TIME)); break; case DX_BAKDATE: memcpy (&date_time, &p->bdat, sizeof (DATE_TIME)); break; default: /** Should never happen **/ return; } /** Processing date **/ check_OK(sys$numtim ( timbuf, &date_time)) convert_date_string("TODAY", &today); if (lib$sub_times ( &date_time, &today, &resultant_time) != LIB$_NEGTIM) { /** File created after today **/ if (strlen(p->fn) <= 30) sprintf (str, "%c%-30.30s Today %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", ch, p->fn, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); else sprintf (str, "%c%-29.29s~ Today %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", ch, p->fn, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); } else { convert_date_string("YESTERDAY", &yesterday); if (lib$sub_times ( &date_time, &yesterday, &resultant_time) != LIB$_NEGTIM) { /** File created after yesterday **/ if (strlen(p->fn) <= 30) sprintf (str, "%c%-30.30s Yesterdy %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", ch, p->fn, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); else sprintf (str, "%c%-29.29s~ Yesterdy %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", ch, p->fn, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); } else { /** File created earlier than yesterday **/ check_OK(lib$sub_times ( &today, &yesterday, &delta_time)) check_OK(lib$day_of_week ( 0, &day_number)) day_number %= 7; memcpy (&weekday, &yesterday, sizeof (DATE_TIME)); for (g = day_number-2; g >= 0; g--) { check_OK(lib$sub_times ( &weekday, &delta_time, &weekday)) if (lib$sub_times ( &date_time, &weekday, &resultant_time) != LIB$_NEGTIM) { break; } } switch (g) { case 4: strcpy(wday, "Thursday"); break; case 3: strcpy(wday, "Wednesdy"); break; case 2: strcpy(wday, "Tuesday "); break; case 1: strcpy(wday, "Monday "); break; case 0: strcpy(wday, "Sunday "); break; default: sprintf(wday, "%2.2d/%02.2d/%02.2d", timbuf[0]-1900, timbuf[1], timbuf[2]); break; } if (strlen(p->fn) <= 30) { sprintf (str, "%c%-30.30s", ch, p->fn); } else { sprintf (str, "%c%-29.29s~", ch, p->fn); } if (timbuf[0] == 1858 && timbuf[1] == 11 && timbuf[2] == 17) { if (cntrl_info_block.dir_dx[win].cur_filter.date == DX_EXPDATE) { sprintf (str, "%s %-17.17s %5.5d (%s,%s,%s,%s)", str, "None specified", p->filesize, spro, opro, gpro, wpro); } else if (cntrl_info_block.dir_dx[win].cur_filter.date == DX_BAKDATE) { sprintf (str, "%s %-17.17s %5.5d (%s,%s,%s,%s)", str, "No backup listed", p->filesize, spro, opro, gpro, wpro); } else { sprintf (str, "%s %s %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", str, wday, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); } } else { sprintf (str, "%s %s %2.2d:%02.2d:%02.2d %5.5d (%s,%s,%s,%s)", str, wday, timbuf[3], timbuf[4], timbuf[5], p->filesize, spro, opro, gpro, wpro); } } } } } } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int setddir(dev_dir, errmsg) char *dev_dir; char *errmsg; { struct FAB fab; struct NAM nam; char expand_name[NAM$C_MAXRSS]; char dev[MAXFILESPEC+1]; $DESCRIPTOR (dev_descrip, dev); char dir[MAXFILESPEC+1]; $DESCRIPTOR (dir_descrip, dir); unsigned long int status; /* ** Set default directory even if the directory specified ** does not exist. First change the definition of ** SYS$DISK, and then set default directory. **/ /** 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; fab.fab$l_fna = dev_dir; fab.fab$b_fns = strlen(fab.fab$l_fna); fab.fab$l_nam = &nam; status = sys$parse(&fab, 0, 0); if (!(status & 1)) { strcpy(errmsg, "directory or file specification invalid"); return DX__ERROR; } strncpy (dev, nam.nam$l_dev, nam.nam$b_dev); dev[nam.nam$b_dev] = EOS; strncpy (dir, nam.nam$l_dir, nam.nam$b_dir); dir[nam.nam$b_dir] = EOS; /** Change the definition of SYS$DISK **/ LENGTH(dev_descrip) = strlen(dev); status = lib$set_logical ( $DESCR ("SYS$DISK"), &dev_descrip, 0, 0, 0); if (status != SS$_NORMAL && status != SS$_SUPERSEDE) { strcpy(errmsg, "directory or file specification invalid"); return DX__ERROR; } /** Set new default directory **/ LENGTH(dir_descrip) = strlen(dir); status = sys$setddir ( &dir_descrip, 0, 0); if (!(status & 1)) { strcpy(errmsg, "directory or file specification invalid"); return DX__ERROR; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int highlight_filer_current_file() { int rows_in_page, current_page; char str[81]; $DESCRIPTOR(str_descrip, str); char page_str[81]; $DESCRIPTOR(page_str_descrip, page_str); char row_str[81]; $DESCRIPTOR(row_str_descrip, row_str); int row_beg_y; if (DX_CURRENT_FILE != DX_CURRENT_DIRECTORY.non_dir_filelist) { /** Directory not empty **/ format_filer_entry(DX_CURRENT_FILE, str, cntrl_info_block.cur_win); current_page = 1+(DX_CURRENT_FILE->beg_y-1) / DX_CURRENT_DIRECTORY.filer_display.view_rows; sprintf(page_str, "Pg %d", current_page); LENGTH(page_str_descrip) = strlen(page_str); sprintf(row_str, "Row %d", DX_CURRENT_FILE->beg_y); LENGTH(row_str_descrip) = strlen(row_str); check_OK(smg$begin_display_update ( &DX_CURRENT_DIRECTORY.dir_info_display.id)) check_OK(smg$draw_line ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &1, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &DX_CURRENT_DIRECTORY.dir_info_display.width, 0, 0)) check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &page_str_descrip, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &2, 0, &SMG$M_BOLD, 0, 0)) row_beg_y = LENGTH(page_str_descrip)+4; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.dir_info_display.id, &row_str_descrip, &DX_CURRENT_DIRECTORY.dir_info_display.rows, &row_beg_y, 0, &SMG$M_BOLD, 0, 0)) check_OK(smg$end_display_update ( &DX_CURRENT_DIRECTORY.dir_info_display.id)) if (DX_CURRENT_FILE->fn[ strlen(DX_CURRENT_FILE->fn)-1 ] != ']') { /** Current file is not a directory file **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x, 0, 0, &SMG$M_REVERSE, 0)) } else if (DX_CURRENT_DIRECTORY.form == short_form) { /** Directory file with short form **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x, 0, &SMG$M_BOLD, &SMG$M_REVERSE, 0)) } else { /** Directory file with long form **/ check_OK(smg$begin_display_update ( &DX_CURRENT_DIRECTORY.filer_display.id)) LENGTH(str_descrip) = 1; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &1, 0, 0, &SMG$M_REVERSE, 0)) if (!strcmp(str+1, "[-]")) { check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, $DESCR ("[-]"), &DX_CURRENT_FILE->beg_y, &2, 0, &SMG$M_BOLD, &SMG$M_REVERSE, 0)) } else { int offset; POINTER(str_descrip) = str+1; LENGTH(str_descrip) = min (30, strlen(DX_CURRENT_FILE->fn)); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &2, 0, &SMG$M_BOLD, &SMG$M_REVERSE, 0)) offset = 1+LENGTH(str_descrip); POINTER(str_descrip) = str+offset; LENGTH(str_descrip) = strlen(str+offset); offset++; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &offset, 0, 0, &SMG$M_REVERSE, 0)) } check_OK(smg$end_display_update ( &DX_CURRENT_DIRECTORY.filer_display.id)) } check_OK(smg$set_cursor_abs ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x)) } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int unhighlight_filer_current_file() { char str[81]; $DESCRIPTOR(str_descrip, str); if (DX_CURRENT_FILE != DX_CURRENT_DIRECTORY.non_dir_filelist) { /** Directory not empty **/ format_filer_entry(DX_CURRENT_FILE, str, cntrl_info_block.cur_win); LENGTH(str_descrip) = strlen(str); if (DX_CURRENT_FILE->fn[ strlen(DX_CURRENT_FILE->fn)-1 ] != ']') { /** Current file is not a directory file **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x, 0, 0, 0, 0)) } else if (DX_CURRENT_DIRECTORY.form == short_form) { /** Directory file with short form **/ LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x, 0, &SMG$M_BOLD, 0, 0)) } else { /** Directory file with long form **/ check_OK(smg$begin_display_update ( &DX_CURRENT_DIRECTORY.filer_display.id)) LENGTH(str_descrip) = 1; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &1, 0, 0, 0, 0)) if (!strcmp(str+1, "[-]")) { check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, $DESCR ("[-]"), &DX_CURRENT_FILE->beg_y, &2, 0, &SMG$M_BOLD, 0, 0)) } else { int offset; POINTER(str_descrip) = str+1; LENGTH(str_descrip) = min (30, strlen(DX_CURRENT_FILE->fn)); check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &2, 0, &SMG$M_BOLD, 0, 0)) offset = 1+LENGTH(str_descrip); POINTER(str_descrip) = str+offset; LENGTH(str_descrip) = strlen(str+offset); offset++; check_OK(smg$put_chars ( &DX_CURRENT_DIRECTORY.filer_display.id, &str_descrip, &DX_CURRENT_FILE->beg_y, &offset, 0, 0, 0, 0)) } check_OK(smg$end_display_update ( &DX_CURRENT_DIRECTORY.filer_display.id)) } check_OK(smg$set_cursor_abs ( &cntrl_info_block.dir_dx[cntrl_info_block.cur_win].filer_display.id, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x)) } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** PUT_FILER_TITLE() outputs the header line ** **-- **/ int put_filer_title(unsigned short int win) { char cwd_line[MAXFILESPEC+1]; $DESCRIPTOR (cwd_line_descrip, cwd_line); char mod[10], dir[10]; /** Output cwd line **/ if (cntrl_info_block.dir_dx[win].filemode == single) { strcpy(mod, "Single"); } else { strcpy(mod, "Multiple"); } if (cntrl_info_block.dir_dx[win].direction == advance) { strcpy(dir, "Forward"); } else { strcpy(dir, "Backward"); } if (strlen(cntrl_info_block.dir_dx[win].cur_dir) > 56) { /** Directory name truncated **/ sprintf(cwd_line, " %-55.55s~ | %-8.8s | %-8.8s ", cntrl_info_block.dir_dx[win].cur_dir, dir, mod); } else { /** Directory name fit **/ sprintf(cwd_line, " %-56.56s | %-8.8s | %-8.8s ", cntrl_info_block.dir_dx[win].cur_dir, dir, mod); } LENGTH(cwd_line_descrip) = strlen(cwd_line); check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].dir_info_display.id, &cwd_line_descrip, &FILER_DIRECT_ROW, &FILER_DIRECT_COLUMN, &SMG$M_ERASE_LINE, &SMG$M_REVERSE, 0, 0)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int put_filer_stat(unsigned short int win) { char total_str[81], select_str[81]; int spaces; int start_col; char str[MAXFILESPEC+1]; $DESCRIPTOR (str_descrip, str); /* ** Write statistics line **/ /* Put FILER statistics line **/ sprintf(total_str, "total: %ldf/%ldb", cntrl_info_block.dir_dx[win].tot_files, cntrl_info_block.dir_dx[win].tot_blocks); sprintf(select_str, "selections: %ldf/%ldb", cntrl_info_block.dir_dx[win].sel_files, cntrl_info_block.dir_dx[win].sel_blocks); spaces = max (1, FILER_RIGHTMOST-3-(strlen(total_str)+strlen(select_str))); sprintf(str, " %s", total_str); memset (str+strlen(str), ' ', spaces); str[1+strlen(total_str)+spaces] = EOS; strcat(str, select_str); LENGTH(str_descrip) = strlen(str); check_OK(smg$put_chars ( &cntrl_info_block.dir_dx[win].dir_info_display.id, &str_descrip, &FILER_STAT_ROW, &1, &SMG$M_ERASE_TO_EOL, &SMG$M_BOLD, 0, 0)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filter_alarm_working() { static int remain_alarm = 2; if (cntrl_info_block.user_pref.display_clock && cntrl_info_block.user_pref.update_in_second) { write_time(cntrl_info_block.commands_display.id); } remain_alarm--; if (remain_alarm > 0) { signal(SIGALRM, filter_alarm_working); } else { remain_alarm = 2; signal(SIGALRM, filter_alarm_working$1); } alarm(1); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ static int filter_alarm_working$1() { static int switch_on = 0; static int remain_timeout = 60; if (!switch_on) { switch_on++; check_OK(smg$put_chars ( &cntrl_info_block.commands_display.id, $DESCR ("Working..."), &2, &1, 0, 0, 0, 0)) } else { switch_on = 0; check_OK(smg$erase_chars ( &cntrl_info_block.commands_display.id, &10, &2, &1)) } if (cntrl_info_block.user_pref.display_clock) { if (cntrl_info_block.user_pref.update_in_second) { write_time(cntrl_info_block.commands_display.id); } else { remain_timeout--; if (remain_timeout == 0) { write_time(cntrl_info_block.commands_display.id); remain_timeout = 60; } } } signal(SIGALRM, filter_alarm_working$1); alarm(1); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int find_full_path_name( char *fn, char *buf, unsigned short int win) { char *cp; if (!strcmp(fn, "[-]")) { /** This is the parent directory placeholder **/ strcpy(buf, "[-]"); } else if (fn[strlen(fn)-1] != ']') { /** This is a non-directory file **/ if (strchr(fn, ':') != NULL) { strcpy(buf, fn); } else if (fn[0] == '[') { /** Directory name included in the file name **/ size_t len; len = strcspn ( DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->equivalent_name, "["); strncpy (buf, DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->equivalent_name, len); buf[len] = EOS; strcat (buf, fn); } else { /** Directory not included **/ sprintf(buf, "%s%s", cntrl_info_block.dir_dx[win].cur_filter.name_filespec_list->w_dids->equivalent_name, fn); } } else { /** This is a directory file **/ /** Get full directory name **/ if (strchr (fn, ':')) { /** Device name included in the file name **/ strcpy(buf, fn); } else if (*(strchr (fn, '[')+1) != '.') { /** More than one sub-directory **/ size_t len; len = strcspn ( DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->equivalent_name, "["); strncpy ( buf, DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->equivalent_name, len); buf[len] = EOS; strcat(buf, fn); } else { /** Only one sub-directory **/ strcpy (buf, DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->equivalent_name); buf[ strlen(buf)-1 ] = EOS; /** Delete ']' **/ strcat (buf, fn+1); } /** Delete ']' **/ buf[strlen(buf)-1] = EOS; cp = strrchr(buf, '.'); *cp = ']'; /** Change the last '.' to ']' **/ strcat(buf, ".DIR;1"); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int convert_date_string(date_string, date_time) char *date_string; DATE_TIME *date_time; { $DESCRIPTOR (date_string_descrip, date_string); int days_of_month[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; struct { unsigned short year, month, day, hour, minute, second, hundredth_of_second; } timbuf; check_OK(sys$numtim ( &timbuf, 0)) if (timbuf.year % 400 == 0 || (timbuf.year % 4 == 0 && timbuf.year % 100 != 0)) { days_of_month[1] = 29; } if (!strcmp (date_string, "TODAY")) { timbuf.hour = timbuf.minute = timbuf.second = timbuf.hundredth_of_second = 0; } else if (!strcmp (date_string, "YESTERDAY")) { timbuf.hour = timbuf.minute = timbuf.second = timbuf.hundredth_of_second = 0; timbuf.day--; if (timbuf.day < 1) { timbuf.month--; if (timbuf.month > 0) { timbuf.day = days_of_month[timbuf.month-1]; } else { timbuf.year--; timbuf.month = 12; timbuf.day = 31; } } } else if (!strcmp (date_string, "TOMORROW")) { timbuf.hour = timbuf.minute = timbuf.second = timbuf.hundredth_of_second = 0; timbuf.day++; if (timbuf.day > days_of_month[timbuf.month-1] ) { timbuf.day = 1; timbuf.month++; if (timbuf.month > 12) { timbuf.month = 1; timbuf.year++; } } } else { LENGTH(date_string_descrip) = strlen(date_string); check_OK(sys$bintim ( &date_string_descrip, date_time)) check_OK(sys$numtim ( &timbuf, date_time)) } check_OK(lib$cvt_vectim ( &timbuf, date_time)) return DX__NORMAL; }