macutils/binhex/dofile.c

193 lines
3.3 KiB
C

#include "../fileio/machdr.h"
#include "../fileio/rdfile.h"
extern int dorep;
extern unsigned long binhex_crcinit;
extern unsigned long binhex_updcrc();
#define RUNCHAR 0x90
static int pos_ptr;
static char codes[] =
"!\"#$%&'()*+,-012345689@ABCDEFGHIJKLMNPQRSTUVXYZ[`abcdefhijklmpqr";
static int state;
static int savebits;
static int rep_char;
static int rep_count;
void doheader();
void dofork();
void outbyte();
void finish();
void outbyte1();
void out6bit();
void outchar();
void dofile()
{
(void)printf("(This file must be converted; you knew that already.)\n");
(void)printf("\n");
pos_ptr = 1;
state = 0;
rep_char = -1;
rep_count = 0;
outchar(':');
doheader();
dofork(data_fork, data_size);
dofork(rsrc_fork, rsrc_size);
finish();
(void)putchar(':');
(void)putchar('\n');
}
void doheader()
{
unsigned long crc;
int i, n;
crc = binhex_crcinit;
n = file_info[I_NAMEOFF];
crc = binhex_updcrc(crc, file_info + I_NAMEOFF, n + 1);
for(i = 0; i <= n; i++) {
outbyte(file_info[I_NAMEOFF + i]);
}
n = 0;
crc = binhex_updcrc(crc, (char *)&n, 1);
outbyte(0);
crc = binhex_updcrc(crc, file_info + I_TYPEOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_TYPEOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_AUTHOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_AUTHOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_FLAGOFF, 2);
for(i = 0; i < 2; i++) {
outbyte(file_info[I_FLAGOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_DLENOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_DLENOFF + i]);
}
crc = binhex_updcrc(crc, file_info + I_RLENOFF, 4);
for(i = 0; i < 4; i++) {
outbyte(file_info[I_RLENOFF + i]);
}
outbyte((int)(crc >> 8));
outbyte((int)(crc & 0xff));
}
void dofork(fork, size)
char *fork;
int size;
{
unsigned long crc;
int i;
crc = binhex_updcrc(binhex_crcinit, fork, size);
for(i = 0; i < size; i++) {
outbyte(fork[i]);
}
outbyte((int)(crc >> 8));
outbyte((int)(crc & 0xff));
}
void outbyte(b)
int b;
{
b &= 0xff;
if(dorep && (b == rep_char)) {
if(++rep_count == 254) {
outbyte1(RUNCHAR);
outbyte1(255);
rep_char = -1;
rep_count = 0;
}
} else {
if(rep_count > 0) {
if(rep_count > 3) {
outbyte1(RUNCHAR);
outbyte1(rep_count + 1);
} else {
while(rep_count-- > 0) {
outbyte1(rep_char);
}
}
}
outbyte1(b);
if(b == RUNCHAR) {
outbyte1(0);
rep_char = -1;
} else {
rep_char = b;
}
rep_count = 0;
}
}
void finish()
{
if(rep_count > 0) {
if(rep_count > 3) {
outbyte1(RUNCHAR);
outbyte1(rep_count + 1);
} else {
while(rep_count-- > 0) {
outbyte1(rep_char);
}
}
}
switch(state) {
case 1:
out6bit(savebits << 4);
break;
case 2:
out6bit(savebits << 2);
break;
default:
break;
}
}
void outbyte1(b)
int b;
{
switch(state) {
case 0:
out6bit(b >> 2);
savebits = b & 0x3;
state = 1;
break;
case 1:
b |= (savebits << 8);
out6bit(b >> 4);
savebits = b & 0xf;
state = 2;
break;
case 2:
b |= (savebits << 8);
out6bit(b >> 6);
out6bit(b & 0x3f);
state = 0;
break;
}
}
void out6bit(c)
char c;
{
outchar(codes[c & 0x3f]);
}
void outchar(c)
char c;
{
(void)putchar(c);
if(++pos_ptr > 64) {
(void)putchar('\n');
pos_ptr = 1;
}
}