/************************************************************************* Copyright (c) 1984 by Nick de Smith This software is supplied for interest and non-profit making purposes only. Under no circumstance shall it be lent, copied or otherwise used for profit. All rights regarding the use and ownership of this software shall at all times remain with the author, who does not guarantee the accuracy or reliabilty of this software and who will not accept any liability for its use. This software may not be copied or distributed without the inclusion of the above copyright notice. January 31st 1984 *************************************************************************/ /************************************************************************* Program : EXPLODE Module : root Author : Nick de Smith November/December 1982 Description : This program takes a set of concatanated object modules and separates them into a set of files called EXPnnn.OBJ, where 'nnn' is a right justified zero filled three digit number starting at '000'. *************************************************************************/ #define MAIN #include #define local static /* Not a global entry point */ #define global /* Global entry point */ FILE *ip; /* Input filename */ FILE *op; /* Output file pointer */ char *version = "EXPLODE x1.0, Jan '83"; /* Version/id */ int debug; /* In debug mode */ int rec_num; /* Current record number */ int out_fil; /* Number of output files */ char outfil[] = "EXP00/.OBJ"; /* Output file names */ /* NB. '/' == '0' - 1 */ #define MAX_RECLEN 512 /* Absolute max buffer length */ typedef struct buffer { int b_next; /* Pointer to next byte */ int b_left; /* Number of bytes left */ int b_length; /* Length of record */ char b_text[MAX_RECLEN]; /* Actual data */ } BUFFER, *BUFFER_PTR; BUFFER buff_1; /* Input buffer #1 */ BUFFER_PTR b_ptr = &buff_1; /* Current working buffer */ /************************************************************************* * * * m a i n * ------- * * Main program start point. * *************************************************************************/ global main(argc, argv) int argc; char *argv[]; { register int i,c; register char *p; char *file; file = NULL; for (i = 1; i < argc; ++i) { p = argv[i]; if (*p++ == '-') { while (c = *p++) { switch (isupper(c) ? tolower(c) : c) { case 'd': debug++; break; default: usage(); } } } else if (file) usage(); else file = argv[i]; } if (!file) usage(); explode(file); } /************************************************************************* * * * e x p l o d e * ------------- * * Shatter the input file * *************************************************************************/ local explode(file) char *file; { register int type; open_in(file); rec_num = 0; read_record(); while (!feof(ip)) { if (!op) open_out(); write_record(); if (next_word() == 6) { close(op); op = NULL; } read_record(); }; close(ip); printf("Stats: %d record%s read, %d output file%s written\n", rec_num, rec_num != 1 ? "s" : "", out_fil, out_fil != 1 ? "s" : ""); } /************************************************************************* * * * o p e n _ i n * ------------- * * Open the named file for input. * *************************************************************************/ local open_in(file_) char *file_; { if (!(ip = fopen(file_, "ru"))) error("Failed to open \"%s\"", file_); } /************************************************************************* * * * o p e n _ o u t * --------------- * * Open an output file. * *************************************************************************/ local open_out() { out_fil++; if (++outfil[5] > '9') { outfil[5] = '0'; if (++outfil[4] > '9') { outfil[4] = '0'; if (++outfil[3] > '9') outfil[3] = 'A'; } } printf("Opening \"%s\"\n", outfil); if (!(op = fopen(outfil, "wnu"))) error("Failed to create \"%s\"", outfil); } /************************************************************************* * * * c l o s e * --------- * * Close the specified file. * *************************************************************************/ local close(fp) FILE *fp; { if (fclose(fp)) error("Failed to close stream"); } /************************************************************************* * * * w r i t e _ r e c o r d * ----------------------- * * read the next variable length record from the input file. * *************************************************************************/ local write_record() { b_ptr->b_length = fput(b_ptr->b_text, b_ptr->b_length, op); } /************************************************************************* * * * r e a d _ r e c o r d * --------------------- * * read the next variable length record from the input file. * *************************************************************************/ local read_record() { b_ptr->b_left = b_ptr->b_length = fget(b_ptr->b_text, MAX_RECLEN, ip); b_ptr->b_next = 0; if (!feof(ip)) rec_num++; } /************************************************************************* * * * n e x t _ b y t e * ----------------- * * Get the next byte from the specified buffer. * *************************************************************************/ local next_byte() { b_ptr->b_left--; return(b_ptr->b_text[b_ptr->b_next++] & 0377); } /************************************************************************* * * * n e x t _ w o r d * ----------------- * * Get the next aligned word from the specified buffer. * *************************************************************************/ local next_word() { b_ptr->b_next += (b_ptr->b_next & 1); /* Align to next word */ b_ptr->b_left = b_ptr->b_length - b_ptr->b_next; return(next_two_bytes(b_ptr)); } /************************************************************************* * * * n e x t _ t w o _ b y t e s * --------------------------- * * Get the next two bytes from the current input record as * a non-aligned word. * *************************************************************************/ local next_two_bytes() { register int temp; temp = next_byte(); return(temp | (0400 * next_byte())); } /************************************************************************* * * * u s a g e * --------- * * How to luse this utility. * *************************************************************************/ local usage() { fprintf(stderr, "Usage: explode file.typ\n"); exit(1); }