home *** CD-ROM | disk | FTP | other *** search
- /*
- * JET PAK - HP DeskJet and LaserJet series printer utilities
- *
- * JETRST program - restore soft font file from symbolic dump
- *
- * Version 1.1 (Public Domain)
- */
-
- /* system include files */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /* application include files */
- #include "patchlev.h"
- #include "jetfont.h"
- #include "jetutil.h"
- #include "jetbmp.h"
-
- /*
- * MODULE GLOBAL DATA
- */
-
- /* scratch area for decompressed DJ bitmap */
- static char scratch[BITMAP_SIZE_MAX];
-
- /* token read from file */
- static char token[1000];
-
- /* input line being read (used for error reporting only) */
- static int line;
-
- /* font command being processed */
- static FONT_COMMAND fc;
-
- /* get_token() can return these values (also EOF) */
- #define TOKEN_KEYWORD 1
- #define TOKEN_DATA 2
-
- /* unget_token() stores the previous result here */
- static int unget_value;
-
- /*
- * LOCAL FUNCTIONS
- */
-
- static void usage_wrong()
- {
- /*
- * Print usage message and exit.
- */
- fprintf(stderr, USAGE_HEADER);
- fprintf(stderr, "Usage: JETRST [-h] dumpfile [dumpfile...]\n\n");
- fprintf(stderr, "Restore soft font files from symbolic listings\n\n");
- fprintf(stderr, " -h print this usage information\n");
- fprintf(stderr, " dumpfile dump file name\n");
- exit(1);
- }
-
- #define STATE_WAITING 0
- #define STATE_INTOKEN 1
- #define STATE_INSTRING 2
- #define STATE_EXIT 3
-
- static int get_token(infp)
- FILE *infp;
- {
- /*
- * Read the next token from the dump file.
- *
- * Tokens are separated by white space (space, tab, new line, and
- * form feed); they may also be terminated by special characters
- * such as quote ("), comment indicator or keyword indicator.
- *
- * Data may be enclosed in quotes in which case white space may
- * legimiately be included as part of the data; within quotes,
- * \ is used to escape '"' and '\'.
- *
- * This routine returns EOF at end of file, TOKEN_KEYWORD if it
- * finds a token beginning with the keyword indicator, otherwise
- * TOKEN_DATA is returned.
- */
- int c, result = EOF, i = 0, state = STATE_WAITING;
- int newline_warning = FALSE, token_warning = FALSE;
-
- /* check for pushed back token */
- if (unget_value != 0)
- {
- result = unget_value;
- unget_value = 0;
- }
- else
- {
- do
- {
- switch(c = getc(infp))
- {
- case EOF:
- ungetc(c, infp);
- token[i] = '\0';
- state = STATE_EXIT;
- break;
-
- case '\n':
- case '\f':
- case ' ':
- case '\t':
- if (state == STATE_INTOKEN)
- {
- /* white space terminates token */
- ungetc(c, infp);
- token[i] = '\0';
- state = STATE_EXIT;
-
- /* don't increment line count here, because the
- /n is pushed back and re-read! */
- }
- else if (state == STATE_INSTRING)
- {
- /* give warning first time newline is found in a
- string as this is probably an error */
- if (c == '\n')
- {
- if (!newline_warning)
- {
- newline_warning = TRUE;
- fprintf(stderr, WARNING_STRING_NL,
- os_dir, os_file, line);
- }
-
- line++; /* line completed */
- }
-
- /* space and tab allowed in string */
- token[i++] = (char)c;
- }
- else /* state == STATE_WAITING */
- {
- if (c == '\n')
- line++; /* line completed */
- }
- break;
-
- case COMMENT_CHARACTER:
- if (state == STATE_WAITING)
- {
- /* consume comment */
- while ((c = getc(infp)) != EOF && c != '\n')
- ;
- ungetc(c, infp);
-
- if (c == EOF)
- {
- token[i] = '\0';
- state = STATE_EXIT;
- }
- }
- else if (state == STATE_INSTRING)
- {
- /* comment character is just part of the string */
- token[i++] = (char)c;
- }
- else /* state == STATE_INTOKEN */
- {
- /* comment character terminates token */
- ungetc(c, infp);
- token[i] = '\0';
- state = STATE_EXIT;
- }
- break;
-
- case KEYWORD_CHARACTER:
- if (state == STATE_WAITING)
- {
- /* start of keyword token*/
- result = TOKEN_KEYWORD;
- state = STATE_INTOKEN;
- }
- /* keyword character is just part of the token */
- token[i++] = (char)c;
- break;
-
- case '"':
- if (state == STATE_WAITING)
- {
- /* start of string data */
- result = TOKEN_DATA;
- state = STATE_INSTRING;
- }
- else if (state == STATE_INSTRING)
- {
- /* end of string data */
- token[i] = '\0';
- state = STATE_EXIT;
- }
- else /* state == STATE_INTOKEN */
- {
- /* quote character terminates a token */
- ungetc(c, infp);
- token[i] = '\0';
- state = STATE_EXIT;
- }
- break;
-
- case '\\':
- if (state == STATE_INSTRING)
- {
- /* escaped '\' or '"' */
- if ((c = getc(infp)) == EOF)
- {
- ungetc(c, infp);
- token[i] = '\0';
- state = STATE_EXIT;
- break;
- }
- }
-
- /* !! INTENTIONAL DROP-THROUGH !! */
-
- default:
- if (state == STATE_WAITING)
- {
- /* start of regular data */
- result = TOKEN_DATA;
- state = STATE_INTOKEN;
- }
- /* regular character as part of token or string */
- token[i++] = (char)c;
- break;
- }
-
- /* check for token overflow */
- if (i == sizeof(token))
- {
- i--;
-
- if (!token_warning)
- {
- token_warning = TRUE;
- fprintf(stderr, WARNING_TOKEN_OVERFLOW,
- os_dir, os_file, line-1);
-
- }
- }
-
- } while (state != STATE_EXIT);
- }
-
- return(result);
- }
- static void unget_token(result)
- int result;
- {
- /*
- * Push back token so it will be returned by the next
- * get_token(). Only one level of unget_token() is supported.
- */
- unget_value = result;
- }
-
- static int get_unsigned_byte(infp, p)
- FILE *infp;
- UNSIGNEDBYTE *p;
- {
- /*
- * Read a token to be interpreted as UNSIGNEDBYTE; store the
- * result in *p, if data is read successfully.
- */
- int result;
- UNSIGNEDINT value;
-
- if ((result = get_token(infp)) == TOKEN_DATA)
- {
- sscanf(token, "%hu", &value);
- *p = (UNSIGNEDBYTE)value;
- }
-
- return(result);
- }
- static int get_signed_byte(infp, p)
- FILE *infp;
- SIGNEDBYTE *p;
- {
- /*
- * Read a token to be interpreted as SIGNEDBYTE; store the
- * result in *p, if data is read successfully.
- */
- int result;
- SIGNEDINT value;
-
- if ((result = get_token(infp)) == TOKEN_DATA)
- {
- sscanf(token, "%hd", &value);
- *p = (SIGNEDBYTE)value;
- }
-
- return(result);
- }
- static int get_unsigned_int(infp, p)
- FILE *infp;
- UNSIGNEDINT *p;
- {
- /*
- * Read a token to be interpreted as UNSIGNEDINT; store the
- * result in *p, if data is read successfully.
- */
- int result;
-
- if ((result = get_token(infp)) == TOKEN_DATA)
- sscanf(token, "%hu", p);
-
- return(result);
- }
- static int get_signed_int(infp, p)
- FILE *infp;
- SIGNEDINT *p;
- {
- /*
- * Read a token to be interpreted as SIGNEDINT; store the
- * result in *p, if data is read successfully.
- */
- int result;
-
- if ((result = get_token(infp)) == TOKEN_DATA)
- sscanf(token, "%hd", p);
-
- return(result);
- }
-
- static int bitmap_data_restore(infp, bp, cw, ch, dsize)
- FILE *infp;
- UNSIGNEDBYTE *bp;
- UNSIGNEDINT cw, ch;
- UNSIGNEDINT dsize;
- {
- /*
- * Restore the data in the bitmap record, returning the number of
- * bytes read if successful.
- */
- int result;
- register UNSIGNEDBYTE *bp2 = bp;
- register UNSIGNEDINT pmask;
- UNSIGNEDINT x, len;
-
- /* check sufficient space is available */
- if ((((cw + 7)/8)*ch) > dsize)
- return(ERROR);
-
- while (ch-- > 0)
- {
- /* read a row - tolerate (ie clear) missing rows at bottom of bitmap */
- if ((result = get_token(infp)) == TOKEN_DATA)
- {
- len = strlen(token);
- }
- else
- {
- unget_token(result);
- len = 0;
- }
-
- *bp2 = 0;
- for (x = 0, pmask = 0x80; x < cw; x++, pmask >>= 1)
- {
- if (pmask == 0)
- {
- pmask = 0x80;
- bp2++;
- *bp2 = 0;
- }
-
- /* tolerate (ie clear) missing bits at end of row */
- if ((x < len) && (token[x] == '@'))
- *bp2 |= pmask;
- }
- bp2++;
- }
-
- return((int)(bp2 - bp));
- }
-
- static int bitmap_restore(infp, outfp)
- FILE *infp;
- FILE *outfp;
- {
- /*
- * Restore a bitmap record
- */
- int result;
-
- /* read the bitmap data */
- switch(fc.data.character.format)
- {
- default:
- case LJCHARFORMAT:
- if ((result = bitmap_data_restore(infp,
- fc.data.character.data.ljchar.bitmap,
- fc.data.character.data.ljchar.character_width,
- fc.data.character.data.ljchar.character_height,
- sizeof(fc.data.character.data.ljchar.bitmap))) == ERROR)
- {
- fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
- return(ERROR);
- }
- fc.number += result;
-
- break;
- case DJCHARFORMAT:
- case DJPCHARFORMAT:
- case DJ500CHARFORMAT:
- if ((result = bitmap_data_restore(infp,
- scratch,
- fc.data.character.data.djchar.character_width,
- PASS_HEIGHT,
- sizeof(scratch))) == ERROR)
- {
- fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
- return(ERROR);
- }
-
- if ((result = bitmap_compress(scratch,
- fc.data.character.data.djchar.character_width,
- PASS_HEIGHT,
- fc.data.character.data.djchar.bitmap,
- sizeof(fc.data.character.data.djchar.bitmap))) == ERROR)
- {
- fprintf(stderr, ERROR_BITMAP_TOO_BIG, os_dir, os_file);
- return(ERROR);
- }
- fc.number += result;
-
- break;
- }
-
- /* write out the character descriptor and associated bitmap */
- if (font_command_write(outfp, &fc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- return(ERROR);
- }
-
- return(OK);
- }
-
- static int header_data_restore(infp)
- FILE *infp;
- {
- /*
- * Restore the data in the header record
- */
- FONT_DESCRIPTOR *fdp = &fc.data.font;
- int result;
-
- fc.command_type = FDC;
-
- if ((result = get_unsigned_int(infp, &fdp->size)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->header_format)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->type)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->reserved1)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->baseline_distance)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->cell_width)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->cell_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->orientation)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->spacing)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->symbol_set)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->pitch)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->x_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->width_type)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->style)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->stroke_weight)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->typeface)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->slant)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->serif_style)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->quality)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->placement)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->underline_distance)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->underline_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->text_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->text_width)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->first_code)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->last_code)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->pitch_extended)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->height_extended)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->reserved2)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->font_number_top)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->font_number_bot)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->h_pixel_resolution)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->v_pixel_resolution)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->tdu_distance)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->tdu_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_signed_byte(infp, &fdp->bdu_distance)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->bdu_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->specific_size)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->data_size)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->unidirection)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->compressed)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->hold_time_factor)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->no_half_pitch)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->no_double_pitch)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->no_half_height)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->no_bold)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->no_draft)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->bold_method)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_byte(infp, &fdp->reserved3)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->baseline_offset_2)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->baseline_offset_3)) != TOKEN_DATA)
- return(result);
-
- if ((result = get_unsigned_int(infp, &fdp->baseline_offset_4)) != TOKEN_DATA)
- return(result);
-
- return(get_token(infp));
- }
-
- static int header_restore(infp, outfp)
- FILE *infp;
- FILE *outfp;
- {
- /*
- * Restore the font descriptor records
- */
- int result;
-
- /* check for header keyword */
- if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
- || (strcmp(token, KEYWORD_HEADER) != 0) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- /* get header data and check for name keyword */
- if ( ((result = header_data_restore(infp)) != TOKEN_KEYWORD)
- || (strcmp(token, KEYWORD_NAME) != 0) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- /* get name data */
- if ((result = get_token(infp)) != TOKEN_DATA)
- {
- fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
- strncpy(fc.data.font.name, token, sizeof(fc.data.font.name));
-
- if (fc.data.font.header_format == DJ500FONTFORMAT)
- {
- /* also copy the name extension for DJ500 only */
- strncpy(fc.data.font.name_extension, token+sizeof(fc.data.font.name),
- sizeof(fc.data.font.name_extension));
- }
-
- /* fix up the descriptor size and number */
- switch(fc.data.font.header_format)
- {
- default:
- fprintf(stderr, WARNING_BAD_FONT_FORMAT,
- os_dir, os_file, fc.data.font.header_format);
-
- /* !! INTENTIONAL DROP-THROUGH !! */
-
- case LJFONTFORMAT:
- fc.data.font.size = LJFDSIZE;
- fc.number = LJFDSIZE+LJSSIZE;
-
- break;
- case DJFONTFORMAT:
- case DJPFONTFORMAT:
- fc.data.font.size = DJFDSIZE;
- fc.number = DJFDSIZE+DJSSIZE;
-
- break;
- case DJ500FONTFORMAT:
- fc.data.font.size = DJ500FDSIZE;
- fc.number = DJ500FDSIZE+DJ500SSIZE;
-
- break;
- }
-
- /* check for comment keyword */
- if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
- || (strcmp(token, KEYWORD_COMMENT) != 0) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- /* get comment data */
- if ((result = get_token(infp)) != TOKEN_DATA)
- {
- fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
- strncpy(fc.data.font.comment, token, COMMENT_SIZE_MAX-1);
- fc.data.font.comment[COMMENT_SIZE_MAX-1] = '\0'; /* failsafe */
- fc.number += strlen(fc.data.font.comment);
-
- /* write out the header */
- if (font_command_write(outfp, &fc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- return(ERROR);
- }
-
- return(OK);
- }
-
- static int character_data_restore(infp)
- FILE *infp;
- {
- /*
- * Restore the data in the character descriptor
- */
- struct ljchar_struct *ljcp;
- struct djchar_struct *djcp;
- int result;
-
- fc.number = 0;
- fc.command_type = CDC;
-
- if ((result = get_unsigned_byte(infp, &fc.data.character.format)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &fc.data.character.continuation)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- switch(fc.data.character.format)
- {
- default:
- fprintf(stderr, WARNING_BAD_CHAR_FORMAT,
- os_dir, os_file, fc.data.character.format);
-
- /* !! INTENTIONAL DROP-THROUGH !! */
-
- case LJCHARFORMAT:
- ljcp = &fc.data.character.data.ljchar;
-
- if ((result = get_unsigned_byte(infp, &ljcp->descriptor_size)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &ljcp->class)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &ljcp->orientation)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &ljcp->reserved)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_signed_int(infp, &ljcp->left_offset)) != TOKEN_DATA)
- return(result);
- fc.number += 2;
-
- if ((result = get_signed_int(infp, &ljcp->top_offset)) != TOKEN_DATA)
- return(result);
- fc.number += 2;
-
- if ((result = get_unsigned_int(infp, &ljcp->character_width)) != TOKEN_DATA)
- return(result);
- fc.number += 2;
-
- if ((result = get_unsigned_int(infp, &ljcp->character_height)) != TOKEN_DATA)
- return(result);
- fc.number += 2;
-
- if ((result = get_signed_int(infp, &ljcp->delta_x)) != TOKEN_DATA)
- return(result);
- fc.number += 2;
-
- break;
- case DJCHARFORMAT:
- case DJPCHARFORMAT:
- case DJ500CHARFORMAT:
- djcp = &fc.data.character.data.djchar;
-
- if ((result = get_unsigned_byte(infp, &djcp->descriptor_size)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &djcp->char_type)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &djcp->character_width)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_unsigned_byte(infp, &djcp->comp_width)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_signed_byte(infp, &djcp->left_offset)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- if ((result = get_signed_byte(infp, &djcp->right_offset)) != TOKEN_DATA)
- return(result);
- fc.number += 1;
-
- break;
- }
-
- return(get_token(infp));
- }
-
- static int character_restore(infp, outfp)
- FILE *infp;
- FILE *outfp;
- {
- /*
- * Restore a character descriptor record
- */
- int result;
-
- /* get and output the character code first */
- if ((result = get_token(infp)) != TOKEN_DATA)
- {
- fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- fc.command_type = CCC;
- sscanf(token, "%d", &fc.number);
-
- /* write out the character code escape sequence */
- if (font_command_write(outfp, &fc) == ERROR)
- {
- fprintf(stderr, ERROR_FILE_WRITE_FAILED, os_dir, os_file);
- return(ERROR);
- }
-
- /* get character data and check for bitmap keyword */
- if ( ((result = character_data_restore(infp)) != TOKEN_KEYWORD)
- || (strcmp(token, KEYWORD_BITMAP) != 0) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- unget_token(result);
-
- return(OK);
- }
-
- static int file_restore(infp, outfp)
- FILE *infp;
- FILE *outfp;
- {
- int result;
-
- /* read the header information first */
- if (header_restore(infp, outfp) == ERROR)
- return(ERROR);
-
- while ( ((result = get_token(infp)) == TOKEN_KEYWORD)
- && (strcmp(token, KEYWORD_CHAR) == 0) )
- {
- /* restore the character descriptor header */
- if (character_restore(infp, outfp) == ERROR)
- return(ERROR);
-
- /* must get bitmap data next */
- if ( ((result = get_token(infp)) != TOKEN_KEYWORD)
- || (strcmp(token, KEYWORD_BITMAP) != 0) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- /* restore character descriptor bitmap data */
- if (bitmap_restore(infp, outfp) == ERROR)
- return(ERROR);
- }
-
- /* check loop was exited either at EOF or on reading start of next
- dumped file */
- if ( (result == TOKEN_KEYWORD && strcmp(token, KEYWORD_FILE) != 0)
- || (result == TOKEN_DATA) )
- {
- fprintf(stderr, ERROR_KEYWORD_MISSING, os_dir, os_file, line);
- unget_token(result);
- return(ERROR);
- }
-
- unget_token(result); /* because next token or EOF was read */
-
- return(OK);
- }
-
- static void jetrst()
- {
- char inpath[OS_PATH_LEN], outpath[OS_PATH_LEN];
- FILE *infp, *outfp;
- int result, file_found = FALSE;
-
- /* build the input and output file paths */
- strcpy(inpath, os_dir);
- strcat(inpath, os_file);
-
- if (!(infp = fopen(inpath, "r")))
- {
- fprintf(stderr, ERROR_OPEN_READ_FAILED, os_dir, os_file);
- return;
- }
-
- /* initialise per input file data */
- line = 1;
- unget_value = 0;
-
- /* skip up to file keyword or EOF */
- while ((result = get_token(infp)) != EOF)
- {
- if ( (result == TOKEN_KEYWORD)
- && (strcmp(token, KEYWORD_FILE) == 0) )
- {
- file_found = TRUE;
-
- /* read file name */
- if ((result = get_token(infp)) != TOKEN_DATA)
- {
- fprintf(stderr, ERROR_DATA_MISSING, os_dir, os_file, line);
- unget_token(result);
- continue;
- }
-
- strncpy(outpath, token, OS_PATH_LEN-1);
- outpath[OS_PATH_LEN-1] = '\0'; /* fail-safe NULL termination */
-
- /* rudimentary check for input overwriting output */
- if (strcmp(inpath, outpath) == 0)
- {
- fprintf(stderr, ERROR_OVERWRITE, os_dir, os_file);
- continue;
- }
-
- if (!(outfp = fopen(outpath, "wb")))
- {
- fprintf(stderr, ERROR_OPEN_WRITE_FAILED, os_dir, os_file, outpath);
- continue;
- }
-
- if (file_restore(infp, outfp) == OK)
- fprintf(stderr, OK_JETRST, os_dir, os_file, outpath);
-
- fclose(outfp);
- }
- }
-
- if (!file_found)
- fprintf(stderr, ERROR_FILE_READ_FAILED, os_dir, os_file);
-
- fclose(infp);
- }
-
- /*
- * EXTERNAL FUNCTION
- */
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- char c;
-
- /* stop getopt() printing errors */
- opterr = FALSE;
- while ((c = getopt(argc, argv, "h")) != EOF)
- {
- switch (c)
- {
- case 'h':
- case '?':
- /* help required, or invalid option specified */
- usage_wrong();
- }
- }
-
- /* must specify at least one file */
- if (optind >= argc)
- usage_wrong();
-
- /* process file arguments */
- if (os_findfiles((argc - optind), &argv[optind]) == ERROR)
- fprintf(stderr, ERROR_OUT_OF_HEAP);
-
- while (os_getfile() != EOF)
- jetrst();
-
- return(0);
- }
-