/* Program Name : FILERENC.C */ /* Original Author : C. K. Hung */ /* Date : 30-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ /* 03-Jun-1999 JL usage of __FIB */ #include "global.h" #include "endecode.h" #include "filer.h" #include "filercpy.h" #include "filerenc.h" #include "filerque.h" #include "inquire.h" #include #include #include #include /** Record Attributes Area **/ struct raa_tag { unsigned char fat$b_rtype; unsigned char fat$b_rattrib; unsigned short int fat$w_rsize; struct { unsigned short int fat$w_hiblkh; unsigned short int fat$w_hiblkl; } fat$l_hiblk; struct { unsigned short int fat$w_efblkh; unsigned short int fat$w_efblkl; } fat$l_efblk; short int fat$w_ffbyte; unsigned char fat$b_bktsize; unsigned char fat$b_vfcsize; short int fat$w_maxrec; short int fat$w_defext; short int fat$w_gbc; short int spares1; int spares2; short int spares3; short int fat$w_versions; }; /* ** ** INTERNAL FUNCTION PROTOTYPING ** **/ static int filer_encode$2(char *, char *, char *); static int save_stat(char *from, FILE *lzw_file, char *errmsg, unsigned short chan); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_encode() { if (DX_CURRENT_DIRECTORY.filemode == multiple) filer_multiple_encode(); else filer_single_encode(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_multiple_encode() { char dummy[] = ""; char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error encoding file"); multi_get_userinput_and_exec( filer_encode$1, "Multiple Encode", "Encode to: ", "", errmsg); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_single_encode() { char fn[MAXFILESPEC+1]; char errmsg[MAXFILESPEC+1]; if (!strcmp(DX_CURRENT_FILE->fn, "[-]")) { signal_err("Compress a parent directory file not allowed", bell); } else { find_full_path_name(DX_CURRENT_FILE->fn, fn, cntrl_info_block.cur_win); strcpy(errmsg, "Error encoding file"); get_userinput_and_execute( filer_encode$1, "Encode File", "Encode to: ", "", errmsg, fn); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_encode$1(to, from, errmsg) char *to; char *from; char *errmsg; { return filer_encode$2(from, to, errmsg); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int filer_encode$2(from, to, errmsg) char *from; char *to; char *errmsg; { FILE *input_file; FILE *lzw_file; unsigned long status; long vm_len; struct FAB to_fab; struct NAM to_nam; char expand_name[NAM$C_MAXRSS]; int retcode; struct fil_dx_tag temp_entry; struct filespec_list_tag *s; unsigned short int chan; int total_dids; char equ_name[MAXFILESPEC+1], dir_name[MAXFILESPEC+1]; int i; vm_len = TABLE_SIZE*sizeof(unsigned int); if ((status = lib$get_vm ( &vm_len, &code_value, 0)) != SS$_NORMAL) { strcpy(errmsg, "Insufficient virtual memory"); return DX__ERROR; } if ((status = lib$get_vm ( &vm_len, &prefix_code, 0)) != SS$_NORMAL) { strcpy(errmsg, "Insufficient virtual memory"); return DX__ERROR; } vm_len = TABLE_SIZE*sizeof(unsigned char); if ((status = lib$get_vm ( &vm_len, &append_character, 0)) != SS$_NORMAL) { strcpy(errmsg, "Insufficient virtual memory"); return DX__ERROR; } input_file = fopen(from, "r"); if (input_file == NULL) { sprintf(errmsg, "Error opening input file %s", from); return DX__ERROR; } /** Get directory fid and file name of the output file **/ to_fab = cc$rms_fab; to_nam = cc$rms_nam; to_fab.fab$l_fna = to; to_fab.fab$b_fns = strlen(to); to_fab.fab$l_nam = &to_nam; to_fab.fab$l_xab = NULL; to_fab.fab$l_dna = from; to_fab.fab$b_dns = strcspn (from, ";"); to_nam.nam$l_esa = &expand_name; to_nam.nam$b_ess = NAM$C_MAXRSS; if ((status = sys$parse(&to_fab, 0, 0)) != RMS$_NORMAL) { sprintf(errmsg, "Invalid file specification"); return DX__ERROR; } expand_name[to_nam.nam$b_esl] = EOS; lzw_file = fopen(expand_name, "w", "fop=tef"); if (lzw_file == NULL) { sprintf(errmsg, "Error creating output file %s", expand_name); return DX__ERROR; } /* ** Find the I/O channel for this file **/ strcpy(equ_name, ""); strcpy(dir_name, ""); total_dids = 0; for (s = DX_CURRENT_DIRECTORY.cur_filter.name_filespec_list; s != (struct filespec_list_tag *)NULL; s = s->next) { struct w_dids_tag *t; for (t = s->w_dids; t != (struct w_dids_tag *)NULL; t = t->next) { if (t->did[0] == DX_CURRENT_FILE->did[0] && t->did[1] == DX_CURRENT_FILE->did[1] && t->did[2] == DX_CURRENT_FILE->did[2]) { chan = t->chan; strcpy(dir_name, t->equivalent_name); } if (strcmp(equ_name, t->equivalent_name)) { total_dids++; strcpy(equ_name, t->equivalent_name); } } } if ((retcode = save_stat(from, lzw_file, errmsg, chan)) != DX__NORMAL) { fclose (input_file); fclose (lzw_file); delete (expand_name); return retcode; } compress(input_file, lzw_file); fclose(input_file); fclose(lzw_file); vm_len = TABLE_SIZE*sizeof(unsigned int); if ((status = lib$free_vm( &vm_len, &code_value, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error freeing up virtual memory used"); return DX__ERROR; } if ((status = lib$free_vm( &vm_len, &prefix_code, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error freeing up virtual memory used"); return DX__ERROR; } vm_len = TABLE_SIZE*sizeof(unsigned char); if ((status = lib$free_vm( &vm_len, &append_character, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error freeing up virtual memory used"); return DX__ERROR; } /* ** Get file attributes **/ if (filestat(expand_name, &temp_entry, errmsg) == DX__ERROR) { return DX__ERROR; } if (total_dids > 1) { strcat(dir_name, temp_entry.fn); strcpy(temp_entry.fn, dir_name); } 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 the filer list and display **/ 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; } static int save_stat(char *from, FILE *lzw_file, char *errmsg, unsigned short chan) { static struct fibdef fib; $DESCRIPTOR(fib_descriptor, (char *)&fib); unsigned long status; char filespec[256]; unsigned short filespec_length; $DESCRIPTOR (filespec_descriptor, filespec); /** File Characteristics Bits **/ unsigned long fch; /** Record attribute **/ struct raa_tag raa; /** Statistics Block **/ struct sbkdef asb; /** Access Control Block **/ struct { unsigned short w_size; unsigned short w_type; char *l_addr; } acb[] = { { ATR$S_UCHAR, ATR$C_UCHAR, &fch }, { ATR$S_RECATTR, ATR$C_RECATTR, &raa }, { ATR$S_STATBLK, ATR$C_STATBLK, &asb }, { 0, 0, (char *)NULL }, }; struct { unsigned short status; unsigned short bytcnt; int filler; } iosb; unsigned short len; char *cp; int i; /** Directory fid for the input file **/ for (i = 0; i <= 2; i++) { __FIB(fib,fib$r_did_overlay,fib$w_did[i]) = DX_CURRENT_FILE->did[i]; } /** SYS$QIO will not use device and directory name **/ strcpy(filespec, strchr(from, ']')+1); LENGTH(filespec_descriptor) = strlen(filespec); LENGTH(fib_descriptor) = sizeof (struct fibdef); status = sys$qiow ( /** Read input file attributes **/ 0, chan, IO$_ACCESS+IO$M_ACCESS, &iosb, 0, 0, &fib_descriptor, &filespec_descriptor, 0, 0, acb, 0); if (iosb.status != SS$_NORMAL) { /** No READ access **/ sprintf(errmsg, "Insufficient privilege for read operation"); return DX__ERROR; } switch (raa.fat$b_rtype & 0xF0) { /** Compress only sequential and relative files **/ case FAB$C_SEQ: case FAB$C_REL: break; case FAB$C_IDX: sys$qiow (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fib_descriptor, 0, 0, 0, 0, 0); strcpy(errmsg, "Compression of an Indexed file not supported"); return DX__ERROR; case FAB$C_HSH: sys$qiow (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fib_descriptor, 0, 0, 0, 0, 0); strcpy(errmsg, "Compression of a hashed file not supported"); return DX__ERROR; default: sys$qiow (0, chan, IO$_DEACCESS, &iosb, 0, 0, &fib_descriptor, 0, 0, 0, 0, 0); strcpy(errmsg, "Unknown file organization. Compression aborted"); return DX__ERROR; ; } /** Save input file name **/ len = strlen(filespec); fwrite(&len, sizeof (unsigned short), 1, lzw_file); fwrite (filespec, sizeof (char), len, lzw_file); /** Save input file characteristics **/ fwrite (&fib, sizeof (struct fibdef), 1, lzw_file); fwrite(&fch, sizeof (unsigned long), 1, lzw_file); fwrite(&raa, sizeof (struct raa_tag), 1, lzw_file); fwrite(&asb, sizeof (struct sbkdef), 1, lzw_file); status = sys$qiow ( 0, chan, IO$_DEACCESS, &iosb, 0, 0, &fib_descriptor, 0, 0, 0, 0, 0); if (iosb.status != SS$_NORMAL) { /** File close error **/ sprintf(errmsg, "Error deaccessing file"); return DX__ERROR; } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filestat(fn, e, errmsg) char *fn; struct fil_dx_tag *e; char *errmsg; { struct NAM nam; struct FAB fab; struct XABPRO xabpro; struct XABDAT xabdat; int i; char resultant_name[NAM$C_MAXRSS]; unsigned long int status; /* ** 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 = fn; fab.fab$b_fns = strlen(fn); 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) { /** Open failed **/ e->fid[0] = e->fid[1] = e->fid[2] = 0Xffff; e->fpro = 0Xffff; sprintf(errmsg, "Open file %s failed", fn); return DX__ERROR; } status = sys$close( &fab, 0, 0); /** File name **/ memcpy(e->fn, nam.nam$l_name, nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver); e->fn[nam.nam$b_name+nam.nam$b_type+nam.nam$b_ver] = EOS; /** File id and directory id **/ for (i = 0; i <= 2; i++) { e->fid[i] = nam.nam$w_fid[i]; e->did[i] = nam.nam$w_did[i]; } /** File size **/ e->filesize = fab.fab$l_alq; /** File protection **/ e->fpro = xabpro.xab$w_pro; /** Creation date **/ e->cdat = xabdat.xab$q_cdt; /** Revision date **/ e->rdat = xabdat.xab$q_rdt; /** Expiration date **/ e->edat = xabdat.xab$q_edt; /** Backup date **/ e->bdat = xabdat.xab$q_bdt; return DX__NORMAL; }