/* Program Name : FILEROPT.C */ /* Original Author : C. K. Hung */ /* Date : 3-AUG-1990 */ /* Program Description : */ /* : */ /* Revision History follows */ #include "global.h" #include "dx.h" #include "filer.h" #include "filerkpd.h" #include "fileropt.h" #include "filerque.h" #include "findfile.h" #include "inquire.h" #include #include #include #include /* ** INTERNAL FUNCTION PROTOTYPE **/ static int filer_toggle_form(void); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_update() { char errmsg[MAXFILESPEC+1]; /* ** Output 'working...' message if total processing time ** is longer than 3 seconds. Needs to disable broadcast message ** first because of interference. **/ check_OK(smg$disable_broadcast_trapping ( &cntrl_info_block.pasteboard_id)) signal(SIGALRM, filter_alarm_working); alarm(1); /* ** Re-read this directory **/ filer_filter$1("", "Update", errmsg); /* ** Set the signal back to system default **/ alarm(0); signal(SIGALRM, SIG_DFL); check_OK(smg$erase_chars ( &cntrl_info_block.commands_display.id, &10, &2, &1)) check_OK(smg$set_broadcast_trapping ( &cntrl_info_block.pasteboard_id, broadcast_routine, 0)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FILER_HELP() outputs the help messages for FILER ** **-- **/ int filer_help(topic) char *topic; { unsigned int internal_display_id; $DESCRIPTOR(key, topic); char libnam[80]; $DESCRIPTOR(lib, libnam); FILE *fp; /* Check if logical name "DX$HELPLIB" point to a .HLB file */ sprintf (libnam, "%s",DX$HELPLIB); if ((fp = fopen (libnam, "r")) != NULL){ fclose(fp); } else { /* Check if in DXHELP.HLB is in HELPLIB (DX$HOME) */ sprintf (libnam, "%s%s", HELPLIB, "DXHELP.HLB"); if ((fp = fopen (libnam, "r")) != NULL){ fclose (fp); /* Check if in SYS$HELP */ } else if ((fp = fopen ("SYS$HELP:DXHELP.HLB", "r")) != NULL) { fclose (fp); strcpy (libnam, "SYS$HELP:DXHELP.HLB"); /* Damned you ! You did not install the help file */ } else { signal_err ("Help library not found", bell); return DX__ERROR; } } /** .HLB exist. Output the help messages **/ check_OK(smg$save_physical_screen ( &cntrl_info_block.pasteboard_id, &internal_display_id, 0, 0)) check_OK(smg$set_physical_cursor ( &cntrl_info_block.pasteboard_id, &1, &1)) LENGTH(key) = strlen(topic); LENGTH(lib) = strlen(libnam); lbr$output_help( &lib$put_output, 0, &key, &lib, 0, &lib$get_input); check_OK(smg$restore_physical_screen ( &cntrl_info_block.pasteboard_id, &internal_display_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** FILER_WRITE() calls PRINT_FILER_DISPLAY() to save ** all the file characteristics in the current directory to a file ** **-- **/ int filer_write() { char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error writing to file"); get_userinput_and_execute( print_filer_display, "Write File Characteristics", "File Name: ", "", errmsg, "dummy"); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** PRINT_FILER_DISPLAY() outputs the contents of FILER ** virtual display to a hardcopy. ** **-- **/ int print_filer_display(filespec, dummy, errmsg) char *filespec; char *dummy; char *errmsg; { register k; int i; FILE *dxf; char cwd_line[MAXFILESPEC+1]; char display_line[MAXFILESPEC+1]; $DESCRIPTOR(display_line_descriptor, display_line); char total_str[MAXFILESPEC+1], select_str[MAXFILESPEC+1]; int spaces; char filler[MAXFILESPEC+1]; char msg[MAXFILESPEC+1]; struct fil_dx_tag temp_entry; if ((dxf = fopen(filespec, "w")) == (FILE *)NULL) { sprintf(errmsg, "Error opening %s as output", filespec); return DX__ERROR; } /** Write directory name **/ fprintf(dxf, "Directory: %s\n\n", DX_CURRENT_DIRECTORY.cur_dir); for (i = 1; i <= DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y; i++) { check_OK(smg$read_from_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &display_line_descriptor, 0, &i)) for (k = cntrl_info_block.pasteboard_width; k >= 0; k--) if (isprint(display_line[k]) && !isspace(display_line[k])) { display_line[k+1] = '\n'; break; } else display_line[k] = EOS; fprintf(dxf, "%s", display_line); } /** Write directory statistics **/ sprintf(total_str, " (Total: %ldf/%ldb)", DX_CURRENT_DIRECTORY.tot_files, DX_CURRENT_DIRECTORY.tot_blocks); sprintf(select_str, "(Selections: %ldf/%ldb) ", DX_CURRENT_DIRECTORY.sel_files, DX_CURRENT_DIRECTORY.sel_blocks); spaces = cntrl_info_block.pasteboard_width - (strlen(total_str)+strlen(select_str)); if (spaces <= 0) fprintf(dxf, "\n\n%s%s", total_str, select_str); else { memset(filler, ' ', spaces); filler[spaces] = EOS; fprintf(dxf, "\n\n%s%s%s", total_str, filler, select_str); } if (fclose(dxf) == EOF) { sprintf(errmsg, "Error closing %s", filespec); return DX__ERROR; } /***** Add this file to this display *****/ sprintf(msg, "%d lines written to file %s", DX_CURRENT_DIRECTORY.non_dir_filelist->backward->beg_y+4, filespec); signal_err(msg, silence); /* ** Update the filer list and display **/ strcpy(errmsg, "Screen not updated"); if (filestat(filespec, &temp_entry, errmsg) == DX__ERROR) { return DX__ERROR; } temp_entry.state = waiting; temp_entry.beg_y = temp_entry.beg_x = 0; temp_entry.forward = temp_entry.backward = NULL; /* ** Update cache queue. ** In case of running out of memory, output error message ** but update current display(s) anyway. **/ if (update_filer_cache(temp_entry, add_to_filer_cache, errmsg) == DX__ERROR) { signal_err(errmsg, bell); } /** Add it to the FILER **/ if (add_to_filer(temp_entry, errmsg, cntrl_info_block.cur_win) == DX__ERROR) { return DX__ERROR; } /** Update other windows **/ for (i = 0; i < cntrl_info_block.windows; i++) { if (i != cntrl_info_block.cur_win) { if (add_to_filer(temp_entry, errmsg, i) == DX__ERROR) { return DX__ERROR; } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_goto() { char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error setting cursor to new position"); get_userinput_and_execute( filer_goto$1, "Goto Page", "Page Number: ", "", errmsg, "dummy"); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_goto$1(page_str, dummy, errmsg) char *page_str; char *dummy; char *errmsg; { register int i; struct fil_dx_tag *p; int disp; int page_no; int new_viewport_row; int number_of_scroll; page_no = atoi(page_str); disp = 1 + abs(DX_CURRENT_DIRECTORY.filer_display.view_rows*(page_no-1)); unhighlight_filer_current_file(); for (p = DX_CURRENT_DIRECTORY.dir_filelist->forward; p != DX_CURRENT_DIRECTORY.non_dir_filelist; p = p->forward) { if (disp <= p->beg_y) { break; } else if (p->forward == DX_CURRENT_DIRECTORY.dir_filelist) { if (DX_CURRENT_DIRECTORY.non_dir_filelist == DX_CURRENT_DIRECTORY.non_dir_filelist->forward && p != DX_CURRENT_DIRECTORY.dir_filelist) { break; } else { p = DX_CURRENT_DIRECTORY.non_dir_filelist->forward; } } } DX_CURRENT_FILE = (p == DX_CURRENT_DIRECTORY.non_dir_filelist? DX_CURRENT_DIRECTORY.non_dir_filelist->backward : p); change_filer_viewport(cntrl_info_block.cur_win); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_mark_all() { struct fil_dx_tag *p; struct fil_dx_tag *MARKER; check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) MARKER = DX_CURRENT_DIRECTORY.dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) { filer_mark(p, 1); } MARKER = DX_CURRENT_DIRECTORY.non_dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) { filer_mark(p, 1); } check_OK(smg$set_cursor_abs ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_unmark_all() { struct fil_dx_tag *p; struct fil_dx_tag *MARKER; check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) MARKER = DX_CURRENT_DIRECTORY.dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) { filer_unmark(p, 1); } MARKER = DX_CURRENT_DIRECTORY.non_dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) { filer_unmark(p, 1); } check_OK(smg$set_cursor_abs ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_remark_all() { struct fil_dx_tag *p; struct fil_dx_tag *MARKER; check_OK(smg$begin_pasteboard_update ( &cntrl_info_block.pasteboard_id)) MARKER = DX_CURRENT_DIRECTORY.dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) if (p->state == executed) { filer_mark(p, 1); } MARKER = DX_CURRENT_DIRECTORY.non_dir_filelist; for (p = MARKER->forward; p != MARKER; p = p->forward) if (p->state == executed) { filer_mark(p, 1); } check_OK(smg$set_cursor_abs ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_FILE->beg_y, &DX_CURRENT_FILE->beg_x)) check_OK(smg$end_pasteboard_update ( &cntrl_info_block.pasteboard_id)) return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_short_form() { DX_CURRENT_DIRECTORY.form = short_form; filer_toggle_form(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_long_form() { DX_CURRENT_DIRECTORY.form = long_form; filer_toggle_form(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int filer_toggle_form() { int row, col; int sav_row; int prev_disp_rows; sav_row = DX_CURRENT_FILE->beg_y - DX_CURRENT_DIRECTORY.filer_display.view_beg_y; prev_disp_rows = DX_CURRENT_DIRECTORY.filer_display.rows; check_OK(smg$unpaste_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &cntrl_info_block.pasteboard_id)) check_OK(smg$erase_display ( &DX_CURRENT_DIRECTORY.filer_display.id, 0, 0, 0, 0)) /* ** 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); 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; if (prev_disp_rows < DX_CURRENT_DIRECTORY.filer_display.rows) { check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.rows, 0, 0, 0, 0)) } /* ** 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 (prev_disp_rows > DX_CURRENT_DIRECTORY.filer_display.rows) { check_OK(smg$change_virtual_display ( &DX_CURRENT_DIRECTORY.filer_display.id, &DX_CURRENT_DIRECTORY.filer_display.rows, 0, 0, 0, 0)) } change_filer_viewport(cntrl_info_block.cur_win); 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)) return DX__NORMAL; } /* **++ ** ** GET_QUOTA uses ACP services to examine a user's permanent ** disk quota. Read access to [0,0]QUOTA.SYS;1 is required ** to examine all non-user entries. Current version of DX ** does not call this function, it is put here for possible ** future use. ** **-- **/ int get_quota(unsigned long uic) { int iosb[2]; static struct fibdef1 fib; $DESCRIPTOR (fib_descriptor, (char *)& fib); struct dqfs { long int dqf$l_flags; long int dqf$w_uic; long int dqf$l_usage; long int dqf$l_permquota; long int dqf$l_overdraft; long filler[3]; } from_dqf, to_dqf; $DESCRIPTOR (from_dqf_descriptor, (char *)&from_dqf); $DESCRIPTOR (to_dqf_descriptor, (char *)&to_dqf); int len; from_dqf.dqf$w_uic = uic; LENGTH(from_dqf_descriptor) = sizeof (struct dqfs); LENGTH(to_dqf_descriptor) = sizeof (struct dqfs); LENGTH(fib_descriptor) = sizeof (struct fibdef1); fib.fib$w_cntrlfunc = FIB$C_EXA_QUOTA; check_OK(sys$qiow ( 0, DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list->w_dids->chan, IO$_ACPCONTROL, iosb, 0, 0, &fib_descriptor, &from_dqf_descriptor, &len, &to_dqf_descriptor, 0, 0)) return to_dqf.dqf$l_permquota; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_about() { signal_err(DXVERSION, silence); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_mkdir() { char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error creating a directory"); get_userinput_and_execute( filer_mkdir$1, "Create Directory", "Directory Name: ", "", errmsg, "dummy"); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_mkdir$1(newdir, dummy, errmsg) char *newdir, *dummy, *errmsg; { $DESCRIPTOR (newdir_descrip, newdir); unsigned short int len; char filespec[MAXFILESPEC+1]; char *indx; char name[MAXFILESPEC+1]; struct fil_dx_tag temp_entry; struct NAM nam; struct FAB fab; struct XABPRO xabpro; struct XABDAT xabdat; int i; char resultant_name[NAM$C_MAXRSS]; unsigned long int status; LENGTH(newdir_descrip) = strlen(newdir); if (!(status = (lib$create_dir ( &newdir_descrip, 0, 0, 0, 0, 0)) & 1)) { return DX__ERROR; } /* ** Convert directory spec to file spec **/ strcpy(filespec, newdir); if ((indx = strrchr(filespec, '.')) == NULL) if ((indx = strchr(filespec, '[')) == NULL) return -1; /* ** Get parent directory name **/ indx++; strcpy(name, indx); if ((indx = strchr(name, ']')) == NULL) return -1; *indx = EOS; if (strcmp(name, "000000")) { /* ** Not a system master directory **/ indx = strchr(filespec, ']'); *indx++ = '.'; *indx++ = '-'; *indx++ = ']'; *indx = EOS; } strcat(filespec, name); strcat(filespec, ".DIR;1"); /* ** Get directory file attributes **/ if (filestat(filespec, &temp_entry, errmsg) == DX__ERROR) { strcpy(errmsg, "Error getting directory attributes"); return DX__ERROR; } temp_entry.state = waiting; temp_entry.beg_y = temp_entry.beg_x = 0; temp_entry.forward = temp_entry.backward = NULL; /* ** Update cache queue. ** In case of running out of memory, output error message ** but update current display(s) anyway. **/ if (update_filer_cache(temp_entry, add_to_filer_cache, errmsg) == DX__ERROR) { signal_err(errmsg, bell); } /* ** Update direct queue **/ /** Init RMS$ data structures **/ fab = cc$rms_fab; nam = cc$rms_nam; xabpro = cc$rms_xabpro; xabdat = cc$rms_xabdat; /* ** use RMS service to get the full file spec and ** characteristics. Default directory is cwd. ** **/ fab.fab$l_fna = filespec; fab.fab$b_fns = strlen(fab.fab$l_fna); fab.fab$l_nam = &nam; fab.fab$l_xab = &xabpro; xabpro.xab$l_nxt = &xabdat; nam.nam$l_rsa = &resultant_name; nam.nam$b_rss = sizeof resultant_name; if ((status = sys$open ( &fab, 0, 0)) == RMS$_NORMAL) { resultant_name[nam.nam$b_rsl] = EOS; indx = strchr(resultant_name, ']'); *indx = '.'; indx = strrchr(resultant_name, '.'); *indx = ']'; *++indx = EOS; /** Convert filespec to dirspec **/ status = sys$close( &fab, 0, 0); if (add_to_direct_cache(resultant_name, errmsg) == DX__ERROR) { signal_err(errmsg, bell); } } /** Add it to the FILER **/ if (add_to_filer(temp_entry, errmsg, cntrl_info_block.cur_win) == DX__ERROR) { return DX__ERROR; } /** Update other windows **/ for (i = 0; i < cntrl_info_block.windows; i++) { if (i != cntrl_info_block.cur_win) { if (add_to_filer(temp_entry, errmsg, i) == DX__ERROR) { return DX__ERROR; } } } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_show_buffer() { char errmsg[256]; char numstr[80]; int n; if ((n = select_from_filer_cache()) != -1) { strcpy(errmsg, "Error restoring from filer buffer"); sprintf(numstr, "%-d", n); check_OK(smg$set_cursor_abs ( &cntrl_info_block.commands_display.id, &cntrl_info_block.commands_display.rows, &cntrl_info_block.commands_display.width)) if (filer_filter$1(numstr, "Restore", errmsg) == DX__ERROR) { signal_err(errmsg, bell); } } return DX__NORMAL; }