home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*/
- /* */
- /* Copyright 1989, Doug Boone. FidoNet 119/5 */
- /* (916) 893-9019 Data */
- /* (916) 891-0748 voice */
- /* P.O. Box 5108, Chico, CA. 95928 */
- /* */
- /* This program is not for sale. It is for the free use with Opus systems. */
- /* You may not sell it in ANY way. If you have an access charge to your */
- /* Bulletin Board, consider this to be like Opus, you can ONLY make it */
- /* available for download in an open area, where non-members can get access */
- /* */
- /* If you need to modify this source code, please send me a copy of the */
- /* changes you've made so that everyone can share in the updates. */
- /* */
- /* "Don't rip me off!" -- Tom Jennings, FidoNet's founder */
- /* */
- /*--------------------------------------------------------------------------*/
-
- #include <io.h>
- #include <stdlib.h>
- #include <stdio.h>
- /*#include <conio.h>
- #include <ctype.h> */
- #include <fcntl.h>
- #ifndef TURBOC
- #include <sys\types.h>
- #endif
- #include <sys\stat.h>
- #include <string.h>
- /*#include <time.h> */
- #include "compress.h"
-
- #define MARKER_VALUE 26
- #define BUFFER_SIZE 32768
-
- extern FILE *Log_fp;
- extern void unpack(int,int,long);
-
- typedef struct { /* ARC file header record definition */
- char marker; /* should always be MARKER_VALUE */
- char packtype;
- char name[13];
- long size;
- long datetime;
- unsigned crc;
- long length;
- } compress_header;
-
- void *variables;
- unsigned variable_size;
- char *input_buffer;
- char *output_buffer;
-
- unsigned expand_file(int input_handle, int output_handle, long size, int type)
- {
- unsigned input_remaining; /* data remaining in input block */
- unsigned input_size; /* size of current pass */
- unsigned buf_pos; /* position in input buffer */
- long total_input; /* total input processed */
- long total_output; /* total output processed */
- unsigned output_size; /* size of current output block */
- int done; /* boolean flag when finished */
- int end_of_input; /* boolean flag for last input block */
- int n;
-
- total_input = 0; /* zero counters */
- total_output = 0;
-
- switch(type) {
- case 10: init_expand_Crush(variables); /* initialize variable area */
- break;
-
- case 9: expand_LZW_size();
- init_expand_LZW(variables,13,0);
- break;
-
- case 8: expand_LZW_size();
- read(input_handle,input_buffer,1);
- n = input_buffer[0];
- init_expand_LZW(variables,n,1);
- break;
-
- case 3: init_expand_RLE();
- break;
-
- case 2:
- case 1: unpack(input_handle,output_handle,size);
- return(1);
-
- } /* End of switch */
-
- do { /* for each input block */
- /* read the block */
- input_remaining = read(input_handle, input_buffer, BUFFER_SIZE);
- /* check if buffered input larger than file to be expanded */
- if (total_input + input_remaining > size) {
- input_remaining = (unsigned) (size - total_input);
- }
-
- total_input += input_remaining; /* increment counter */
- end_of_input = total_input == size; /* flag if last input block */
- buf_pos = 0; /* set buffer position to start */
- do {
- input_size = input_remaining; /* maximum input = remaining input */
- output_size = BUFFER_SIZE; /* maximum output = size of buffer */
- switch(type) {
- case 10: done = expand_Crush(input_buffer + buf_pos, &input_size,
- output_buffer, &output_size, variables, end_of_input);
- break;
-
- case 9: done = expand_LZW(input_buffer + buf_pos, &input_size,
- output_buffer, &output_size, variables, end_of_input);
- break;
-
- case 8: done = expand_LZW(input_buffer + buf_pos, &input_size,
- output_buffer, &output_size, variables, end_of_input);
- break;
-
- case 3: done = expand_RLE(input_buffer + buf_pos, &input_size,
- output_buffer, &output_size, end_of_input);
- break;
- } /* End of switch */
-
-
- buf_pos += input_size; /* move pointer */
- input_remaining -= input_size; /* decrement input remaining */
- total_output += output_size; /* increment output counter */
- write(output_handle, output_buffer, output_size); /* write out buffer */
- } while(input_remaining);
- } while (!done);
- return(done);
- }
-
-
- int init_buffers(void) /* allocate buffers + variable area */
- {
- variable_size = expand_Crush_size();
- if ((variables = malloc(variable_size)) == NULL) {
- fprintf(Log_fp,"Not enough memory for Crushing variables\n");
- return(2);
- }
- if ((input_buffer = (char *) malloc(BUFFER_SIZE)) == NULL) {
- fprintf(Log_fp,"Not enough memory for input buffer\n");
- return(2);
- }
- if ((output_buffer = (char *) malloc(BUFFER_SIZE)) == NULL) {
- fprintf(Log_fp,"Not enough memory for output buffer\n");
- return(2);
- }
- return(0);
- }
-
- int unpak(char *source,char *to)
- {
- compress_header header; /* header describing files */
- int input_handle;
- int output_handle;
- long next_file; /* position in input file of next header */
- char *name;
- int result = 1;
- unsigned check = 255;
-
- if ((name = strrchr(to,'\\')) == NULL)
- name = to;
- else
- name++;
- if ((result = init_buffers()) !=0)
- return(2);
-
- if ((input_handle = open(source, O_RDONLY | O_BINARY)) < 0) {
- fprintf(Log_fp,"could not open %s\n",source);
- return(1);
- }
-
-
- _fmode = O_BINARY;
- next_file = 0; /* start at begining of file */
- do {
- lseek(input_handle, next_file, SEEK_SET); /* move to next header */
-
- /* read header */
- if (read(input_handle,&header, sizeof(header)) < sizeof(header))
- break; /* we didn't get a full header, so quit. */
-
- if (header.marker != MARKER_VALUE) /* first byte is always ^Z */
- break;
-
- if (header.packtype == 0) /* last header */
- break;
-
- /* set position of next file */
- next_file = tell(input_handle) + header.size;
-
- if (strcmp(header.name,name) == 0) {
- if ((output_handle = creat(to, S_IREAD | S_IWRITE)) < 0) {
- fprintf(Log_fp,"Could not create %s\n",to);
- return(1);
- }
- result = 1;
- check = expand_file(input_handle, output_handle,
- header.size,header.packtype);
- close(output_handle);
- } /* End of name match */
-
- } while (result == 0); /* until we run out of file, actually. */
- close(input_handle);
- return(check-1);
- }
-
-
-
-