/* Program Name : FILERDEC.C */ /* Original Author : C. K. Hung */ /* Date : 30-MAY-1991 */ /* Program Description : */ /* : */ /* Revision History follows */ /* 03-Jun-1999 JL usaged of __FIB */ #include "global.h" #include "endecode.h" #include "filer.h" #include "filercpy.h" #include "filerdec.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_decode$2(char *from, char *to, char *errmsg); static int create_same(char *output_file_name, FILE *lzw_file, char *errmsg, unsigned short chan); /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_decode() { if (DX_CURRENT_DIRECTORY.filemode == multiple) filer_multiple_decode(); else filer_single_decode(); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** to be specified ** **-- **/ int filer_multiple_decode() { char dummy[] = ""; char errmsg[MAXFILESPEC+1]; strcpy(errmsg, "Error decoding file"); multi_get_userinput_and_exec( filer_decode$1, "Multiple Decode", "Decode to: ", "", errmsg); return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_single_decode() { char fn[MAXFILESPEC+1]; char errmsg[MAXFILESPEC+1]; if (!strcmp(DX_CURRENT_FILE->fn, "[-]")) { signal_err("Expand 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 decoding file"); get_userinput_and_execute( filer_decode$1, "Decode File", "Decode to: ", "", errmsg, fn); } return DX__NORMAL; } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ int filer_decode$1(to, from, errmsg) char *to; char *from; char *errmsg; { return filer_decode$2(from, to, errmsg); } /* **++ ** FUNCTIONAL DESCRIPTION: ** ** tbs ** **-- **/ static int filer_decode$2(from, to , errmsg) char *from; char *to; char *errmsg; { FILE *output_file; FILE *lzw_file; unsigned long status; long vm_len; struct FAB to_fab; struct NAM to_nam; char expand_name[NAM$C_MAXRSS]; 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, &prefix_code, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error allocating virtual memory - exceeded quota"); return DX__ERROR; } vm_len = TABLE_SIZE*sizeof(unsigned char); if ((status = lib$get_vm ( &vm_len, &append_character, 0)) != SS$_NORMAL) { strcpy(errmsg, "Error allocating virtual memory - exceeded quota"); return DX__ERROR; } lzw_file = fopen(from, "r"); if (lzw_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; /* ** 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 (create_same(expand_name, lzw_file, errmsg, chan) == -1) { sprintf(errmsg, "Error creating output file %s", expand_name); return DX__ERROR; } output_file = fopen(expand_name, "r+"); if (output_file == NULL) { sprintf(errmsg, "Error re-opening output file %s", expand_name); return DX__ERROR; } if (expand(errmsg, lzw_file, output_file) != DX__NORMAL) { return DX__ERROR; } fclose(lzw_file); fclose(output_file); vm_len = TABLE_SIZE*sizeof(unsigned int); 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 create_same(char *to, FILE *lzw_file, char *errmsg, unsigned short chan) { static struct fibdef fib; $DESCRIPTOR(fib_descriptor, (char *)&fib); struct FAB to_fab; struct NAM to_nam; char expand_name[NAM$C_MAXRSS]; unsigned long status; char devname[256]; char dirname[256]; char filespec[256]; unsigned short filespec_length; $DESCRIPTOR (filespec_descriptor, filespec); char resultant_name[256]; unsigned short resultant_length; $DESCRIPTOR (resultant_name_descriptor, resultant_name); /** 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; unsigned short chan_o; unsigned short get_chan(char *); /** Get original file name **/ fread (&len, sizeof (unsigned short), 1, lzw_file); if (len > MAXFILESPEC) { sprintf(errmsg, "Source file is not a compressed file"); return DX__ERROR; } fread (filespec, sizeof (char), len, lzw_file); /** Get original file characteristics **/ fread (&fib, sizeof (struct fibdef), 1, lzw_file); fread(&fch, sizeof (unsigned long), 1, lzw_file); fread(&raa, sizeof (struct raa_tag), 1, lzw_file); fread(&asb, sizeof (struct sbkdef), 1, lzw_file); /** Initialize FAB and NAM block **/ to_fab = cc$rms_fab; to_nam = cc$rms_nam; /** Assign value for FAB and NAM block **/ to_fab.fab$l_fna = to; to_fab.fab$b_fns = strlen(to); to_fab.fab$l_nam = &to_nam; to_nam.nam$l_esa = &expand_name; to_nam.nam$b_ess = NAM$C_MAXRSS; /** Get output file characteristics **/ if ((status = sys$parse(&to_fab, 0, 0)) != RMS$_NORMAL) { sprintf(errmsg, "Invalid file specification"); return DX__ERROR; } /** Get a channel for output file **/ strncpy(devname, to_nam.nam$l_dev, to_nam.nam$b_dev); devname[to_nam.nam$b_dev] = '\0'; strncpy(dirname, to_nam.nam$l_dir, to_nam.nam$b_dir); dirname[to_nam.nam$b_dir] = '\0'; if ((chan_o = get_chan(devname)) == 0) { sprintf(errmsg, "Establish a logical link with %s failed", to); return DX__ERROR; } /** Directory fid for the input file **/ __FIB(fib,fib$r_did_overlay,fib$w_did[0]) = to_nam.nam$w_did[0]; __FIB(fib,fib$r_did_overlay,fib$w_did[1]) = to_nam.nam$w_did[1]; __FIB(fib,fib$r_did_overlay,fib$w_did[2]) = to_nam.nam$w_did[2]; __FIB(fib,fib$r_acctl_overlay.fib$r_acctl_bits0,fib$v_write) = 1; /** SYS$QIO will not use device and directory name **/ strncpy(filespec, to_nam.nam$l_name, to_nam.nam$b_name); filespec[to_nam.nam$b_name] = EOS; strncat(filespec, to_nam.nam$l_type, to_nam.nam$b_type); filespec[to_nam.nam$b_name+to_nam.nam$b_type] = EOS; if (strchr(to, ';') == 0) strcat(filespec, ";0"); else { strncat(filespec, to_nam.nam$l_ver, to_nam.nam$b_ver); filespec[to_nam.nam$b_name+to_nam.nam$b_type+to_nam.nam$b_ver] = EOS; } LENGTH(filespec_descriptor) = strlen(filespec); LENGTH(fib_descriptor) = sizeof (struct fibdef); status = sys$qiow ( /** Read input file attributes **/ 0, chan_o, IO$_CREATE+IO$M_CREATE, &iosb, 0, 0, &fib_descriptor, &filespec_descriptor, &resultant_length, &resultant_name_descriptor, acb, 0); if (iosb.status != SS$_NORMAL) { /** No WRITE access **/ sprintf(errmsg, "Insufficient privilege for write operation"); return DX__ERROR; } resultant_name[resultant_length] = EOS; sprintf(to, "%s%s%s", devname, dirname, resultant_name); status = sys$dassgn (chan_o); if (status != SS$_NORMAL) { /** Deassign channel failed **/ sprintf(errmsg, "Error deassigning channel"); return DX__ERROR; } return DX__NORMAL; }