Logo Search packages:      
Sourcecode: macutils version File versions  Download package

hecx.c

#include "hexbin.h"
#ifdef HECX
#include "globals.h"
#include "crc.h"
#include "readline.h"
#include "../util/masks.h"
#include "../util/util.h"
#include "../fileio/machdr.h"
#include "../fileio/wrfile.h"
#include "buffer.h"
#include "printhdr.h"

extern void exit();

static void do_o_forks();
static long make_file();
static void comp_c_crc();
static void comp_e_crc();
static int comp_to_bin();
static int hex_to_bin();
static int hexit();

static int compressed;

/* old format -- process .hex and .hcx files */
void hecx(macname, filename)
char *macname, *filename;
{
    int n;

    for(n = 0; n < INFOBYTES; n++) {
      info[n] = 0;
    }
    compressed = 0;
    /* set up name for output files */
    if(macname[0] == '\0') {
      /* strip directories */
      macname = search_last(filename, '/');
      if(macname == NULL) {
          macname = filename;
      } else {
          macname++;
      }

      /* strip extension */
      n = strlen(macname);
      if(n > 4) {
          n -= 4;
          if(!strncmp(macname + n, ".hex", 4) ||
             !strncmp(macname + n, ".hcx", 4)) {
            macname[n] = '\0';
          }
      }
    }
    n = strlen(macname);
    if(n > F_NAMELEN) {
      n = F_NAMELEN;
    }
    (void)strncpy(mh.m_name, macname, n);
    mh.m_name[n] = '\0';

    /* "#TYPEAUTH$flag"  line already read */
    n = strlen(line);
    if(n >= 6 && line[0] == '#' && line[n-5] == '$') {
      if(n >= 10) {
          (void)strncpy(mh.m_type, &line[1], 4);
      }
      if(n >= 14) {
          (void)strncpy(mh.m_author, &line[5], 4);
      }
      (void)sscanf(&line[n-4], "%4hx", &mh.m_flags);
    }
    transname(mh.m_name, trname, n);
    define_name(trname);
    do_o_forks();
    if(listmode) {
      if(!compressed) {
          (void)fprintf(stderr, "This file is in \"hex\" format.\n");
      } else {
          (void)fprintf(stderr, "This file is in \"hcx\" format.\n");
      }
    }
    print_header0(0);
    print_header1(0, 0);
    info[I_NAMEOFF] = n;
    (void)strncpy(info + I_NAMEOFF + 1, mh.m_name, n);
    (void)strncpy(info + I_TYPEOFF, mh.m_type, 4);
    (void)strncpy(info + I_AUTHOFF, mh.m_author, 4);
    put2(info + I_FLAGOFF, (unsigned long)mh.m_flags);
    put4(info + I_DLENOFF, (unsigned long)mh.m_datalen);
    put4(info + I_RLENOFF, (unsigned long)mh.m_rsrclen);
    put4(info + I_CTIMOFF, (unsigned long)mh.m_createtime);
    put4(info + I_MTIMOFF, (unsigned long)mh.m_modifytime);
    print_header2(0);
    end_put();
}

static void do_o_forks()
{
    int forks = 0, found_crc = 0;
    unsigned long calc_crc, file_crc;

    crc = 0;    /* calculate a crc for both forks */

    set_put(0);
    set_put(1);
    while(!found_crc && readline()) {
      if(line[0] == 0) {
          continue;
      }
      if(forks == 0 && strncmp(line, "***COMPRESSED", 13) == 0) {
          compressed++;
          continue;
      }
      if(strncmp(line, "***DATA", 7) == 0) {
          set_put(1);
          mh.m_datalen = make_file(compressed);
          forks++;
          continue;
      }
      if(strncmp(line, "***RESOURCE", 11) == 0) {
          set_put(0);
          mh.m_rsrclen = make_file(compressed);
          forks++;
          continue;
      }
      if(compressed && strncmp(line, "***CRC:", 7) == 0) {
          found_crc++;
          calc_crc = crc;
          (void)sscanf(&line[7], "%lx", &file_crc);
          break;
      }
      if(!compressed && strncmp(line, "***CHECKSUM:", 12) == 0) {
          found_crc++;
          calc_crc = crc & BYTEMASK;
          (void)sscanf(&line[12], "%lx", &file_crc);
          file_crc &= BYTEMASK;
          break;
      }
    }

    if(found_crc) {
      verify_crc(calc_crc, file_crc);
    } else {
      (void)fprintf(stderr, "missing CRC\n");
#ifdef SCAN
      do_error("hexbin: missing CRC");
#endif /* SCAN */
      exit(1);
    }
}

static long make_file(compressed)
int compressed;
{
    register long nbytes = 0L;

    while(readline()) {
      if(line[0] == 0) {
          continue;
      }
      if(strncmp(line, "***END", 6) == 0) {
          break;
      }
      if(compressed) {
          nbytes += comp_to_bin();
      } else {
          nbytes += hex_to_bin();
      }
    }
    return nbytes;
}

static void comp_c_crc(c)
unsigned char c;
{
    crc = (crc + c) & WORDMASK;
    crc = ((crc << 3) & WORDMASK) | (crc >> 13);
}

static void comp_e_crc(c)
unsigned char c;
{
    crc += c;
}

#define SIXB(c) (((c)-0x20) & 0x3f)

static int comp_to_bin()
{
    char obuf[BUFSIZ];
    register char *ip = line;
    register char *op = obuf;
    register int n, outcount;
    int numread, incount;

    numread = strlen(line);
    outcount = (SIXB(ip[0]) << 2) | (SIXB(ip[1]) >> 4);
    incount = ((outcount / 3) + 1) * 4;
    for(n = numread; n < incount; n++) {  /* restore lost spaces */
      line[n] = ' ';
    }

    n = 0;
    while(n <= outcount) {
      *op++ = SIXB(ip[0]) << 2 | SIXB(ip[1]) >> 4;
      *op++ = SIXB(ip[1]) << 4 | SIXB(ip[2]) >> 2;
      *op++ = SIXB(ip[2]) << 6 | SIXB(ip[3]);
      ip += 4;
      n += 3;
    }

    for(n = 1; n <= outcount; n++) {
      comp_c_crc((unsigned)obuf[n]);
      put_byte(obuf[n]);
    }
    return outcount;
}

static int hex_to_bin()
{
    register char *ip = line;
    register int n, outcount;
    int c;

    n = strlen(line);
    outcount = n / 2;
    for(n = 0; n < outcount; n++) {
      c = hexit((int)*ip++);
      comp_e_crc((unsigned)(c = (c << 4) | hexit((int)*ip++)));
      put_byte((char)c);
    }
    return outcount;
}

static int hexit(c)
int c;
{
    if('0' <= c && c <= '9') {
      return c - '0';
    }
    if('A' <= c && c <= 'F') {
      return c - 'A' + 10;
    }

    (void)fprintf(stderr, "illegal hex digit: %c", c);
#ifdef SCAN
    do_error("hexbin: illegal hex digit");
#endif /* SCAN */
    exit(1);
    /* NOTREACHED */
}
#else /* HECX */
int hecx; /* keep lint and some compilers happy */
#endif /* HECX */


Generated by  Doxygen 1.6.0   Back to index