/* dc42wrap: wrap a "raw" floppy image as an Apple DiskCopy 4.2 file */
/* Eric P. Scott, ana-systems, June 1998 */
/* MacBinary III support added September 1998 */
/* AppleSingle support added November 1998 */
/*
* Copyright 1998 by Eric P. Scott. All rights reserved.
*
* This software is "freeware" but is not in the public domain.
*
* The author grants you a nonexclusive royalty-free license to copy,
* redistribute, and use this software for any purpose provided that
* source distributions retain this entire copyright and license.
* You may not sublicense or distribute modified versions to anyone else
* except as part of another product or program, and modified versions
* must be so labeled.
*
* You are encouraged to give proper credit to the author in binary
* distributions and associated documentation.
*
* This software is provided "as is" with no warranties of any kind,
* including the warranties of merchantability and fitness for a
* particular purpose.
*/
/* On some platforms, you can make "smaller" executables */
/* SunOS 4.1.x: cc -o dc42wrap -s -n -Bdynamic -O dc42wrap.c */
/* NEXTSTEP 3.x: cc -o dc42wrap -s -object -O2 -g dc42wrap.c */
/* Compile with -DGENERATE_MACBINARY_III if you really want MacBinary III */
/* (I don't recommend it.) */
/* See <URL:http://www.lazerware.com/formats/macbinary.html> */
#ifdef __SVR4
#define USE_MEMSET 1
#else
#ifdef linux
/* Linux has bzero(); the man page advocates a less efficient replacement */
#define USE_MEMSET 1
#endif
#ifndef hpux
/* "should" be HAVE_TM_GMTOFF, but autoconf set this confusing precedent */
#define HAVE_TM_ZONE 1
#endif
#endif
#ifdef NeXT
#include <bsd/libc.h>
#else
#include <stdio.h>
#ifdef __STRICT_BSD__
#include <strings.h>
#else
#include <string.h>
#endif
#ifndef __tm_gmtoff
/* compensate for GNU/Linux lossage */
#define __tm_gmtoff tm_gmtoff
#endif
#include <time.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#endif
#ifndef lint
static char sccsid[]="@(#)dc42wrap.c 0.4.2 (ana-systems) 11/23/98";
#endif
#ifndef AUX
#ifdef NeXT
/* NEXTSTEP Encoding to Mac Roman Encoding */
#ifdef __STDC__
const
#endif
unsigned char nsetomac[]={
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127,
202, 203, 231, 229, 204, 128, 129, 130,
233, 131, 230, 232, 237, 234, 235, 236,
32, 132, 241, 238, 239, 205, 133, 244,
242, 243, 134, 32, 32, 181, 32, 214,
169, 193, 162, 163, 218, 180, 196, 164,
219, 32, 210, 199, 220, 221, 222, 223,
168, 208, 160, 224, 225, 32, 166, 165,
226, 227, 211, 200, 201, 228, 194, 192,
32, 212, 171, 246, 247, 248, 249, 250,
172, 32, 251, 252, 32, 253, 254, 255,
209, 177, 32, 32, 32, 136, 135, 137,
139, 138, 140, 141, 143, 142, 144, 145,
147, 174, 146, 187, 148, 149, 32, 150,
32, 175, 206, 188, 152, 151, 153, 155,
154, 190, 157, 156, 158, 245, 159, 32,
32, 191, 207, 167, 32, 216, 32, 32
};
#else
/* ISO Latin 1 Encoding to Mac Roman Encoding */
#ifdef __STDC__
const
#endif
unsigned char iso1tomac[]={
0, 1, 2, 3, 4, 5, 6, 7,
8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23,
24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39,
40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55,
56, 57, 58, 59, 60, 61, 62, 63,
64, 65, 66, 67, 68, 69, 70, 71,
72, 73, 74, 75, 76, 77, 78, 79,
80, 81, 82, 83, 84, 85, 86, 87,
88, 89, 90, 91, 92, 93, 94, 95,
96, 97, 98, 99, 100, 101, 102, 103,
104, 105, 106, 107, 108, 109, 110, 111,
112, 113, 114, 115, 116, 117, 118, 119,
120, 121, 122, 123, 124, 125, 126, 127,
32, 32, 32, 32, 32, 32, 32, 32,
32, 32, 32, 32, 32, 32, 32, 32,
245, 212, 171, 246, 247, 248, 249, 250,
172, 32, 251, 252, 32, 253, 254, 255,
202, 193, 162, 163, 219, 180, 32, 164,
172, 169, 187, 199, 194, 208, 168, 248,
161, 177, 32, 32, 171, 181, 166, 225,
252, 32, 188, 200, 32, 32, 32, 192,
203, 231, 229, 204, 128, 129, 174, 130,
233, 131, 230, 232, 237, 234, 235, 236,
32, 132, 241, 238, 239, 205, 133, 32,
175, 244, 242, 243, 134, 32, 32, 167,
136, 135, 137, 139, 138, 140, 190, 141,
143, 142, 144, 145, 147, 146, 148, 149,
32, 150, 152, 151, 153, 155, 154, 214,
191, 157, 156, 158, 159, 32, 32, 216
};
#endif
#endif
/* See <URL:ftp://ftp.apple.com/dts/aii/ftn/ftn-e0-0005>
*
* DiskCopy 4.2 Image Header
* +---------------+---------------+---------------+---------------+
* 0 | name |
* ~ ~
* | |
* +---------------------------------------------------------------+
* 64 | dataSize=1474560L (1440K) : 737280L (720K) |
* +---------------------------------------------------------------+
* 68 | tagSize=0L |
* +---------------------------------------------------------------+
* 72 | dataChecksum |
* +---------------------------------------------------------------+
* 76 | tagChecksum=0L |
* +---------------+---------------+-------------------------------+
* 80 | diskFormat=3:2|formatByte=0x22| private=0x100 |
* +---------------+---------------+-------------------------------+
* 84
*/
static unsigned char imgh[84]={
/* name */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* dataSize */
0x00, 0x16, 0x80, 0x00,
/* tagSize */
0x00, 0x00, 0x00, 0x00,
/* dataChecksum */
0x00, 0x00, 0x00, 0x00,
/* tagChecksum */
0x00, 0x00, 0x00, 0x00,
/* diskFormat */
0x03,
/* formatByte */
0x22,
/* private */
0x01, 0x00
};
/* 359-byte resource fork template */
/* padded to 128-byte multiple for MacBinary II */
static unsigned char rsrcfork[384]={
/* resource header */
0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x35,
0x00, 0x00, 0x00, 0x35, 0x00, 0x00, 0x00, 0x32,
/* next 240 bytes reserved for resource manager */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
/* resource data */
0x00, 0x00, 0x00, 0x31, 48, '4', '.', '2',
',', ' ', 't', 'a', 'g', ' ', 'c', 'h',
'k', 's', 'u', 'm', '=', '$', '0', '0',
'0', '0', '0', '0', '0', '0', ',', ' ',
'd', 'a', 't', 'a', ' ', 'c', 'h', 'k',
's', 'u', 'm', '=', '$', '?', '?', '?',
'?', '?', '?', '?', '?', 0x00, 0x00, 0x01,
0x00, 0x00, 0x00, 0x01, 0x35, 0x00, 0x00, 0x00,
0x35, 0x00, 0x00, 0x00, 0x32, 0xde, 0xad, 0xbe,
0xef, 0xca, 0xfe, 0x00, 0x00, 0x00, 0x1c, 0x00,
0x32, 0x00, 0x00, 'd', 'C', 'p', 'y', 0x00,
0x00, 0x00, 0x0a, 0x00, 0x00, 0xff, 0xff, 0x00,
0x00, 0x00, 0x00, 0xfe, 0xed, 0xfa, 0xce
};
#ifdef __STDC__
int
main(int argc, char *argv[])
#else
main(argc, argv)
int argc;
char *argv[];
#endif
{
#ifdef __STDC__
void writembh(FILE *, const char *,
unsigned long, unsigned long, long),
writeash(FILE *, const char *,
unsigned long, unsigned long, long, long);
#else
void writembh(), writeash();
#endif
extern int optind;
extern char *optarg;
register char *p, *b;
register int c;
register unsigned long s, n;
int fmt, named;
struct stat st;
char *hname, hbuf[64];
hname=(char *)NULL;
fmt=0;
named=0;
while ((c=getopt(argc, argv, "H:mn:rs"))!=EOF) switch (c) {
case 'm':
if (fmt) {
fmt1:
(void)fprintf(stderr,
"%s: only one -r, -m, or -s may be specified\n", *argv);
exit(1);
}
fmt=2;
break;
case 'r':
if (fmt) goto fmt1;
fmt=1;
break;
case 's':
if (fmt) goto fmt1;
fmt=3;
break;
case 'n':
if (named) {
(void)fprintf(stderr,
"%s: only one -n may be specified\n", *argv);
exit(1);
}
b=optarg;
if ((c=strlen(b))>63) {
(void)fprintf(stderr,
"%s: name limited to 63 characters\n", *argv);
exit(1);
}
#ifdef __STRICT_BSD__
p=index(b, ':');
#else
p=strchr(b, ':');
#endif
if (p) {
(void)fprintf(stderr,
"%s: name may not contain colons\n", *argv);
exit(1);
}
p=(char *)imgh;
*p++=c;
while (c>0) {
if (*b=='.') {
b++;
*p++='\245';
if (--c<=0) break;
}
do {
#ifdef AUX
*p++= *b++;
#else
*(unsigned char *)p++=
#ifdef NeXT
nsetomac[*(unsigned char *)b++];
#else
iso1tomac[*(unsigned char *)b++];
#endif
#endif
} while (--c>0);
break;
/*NOTREACHED*/
}
named++;
break;
case 'H':
if (hname) {
(void)fprintf(stderr,
"%s: only one -H may be specified\n", *argv);
exit(1);
}
if (strlen(optarg)>63) {
(void)fprintf(stderr,
"%s: file name limited to 63 characters\n",
*argv);
exit(1);
}
#ifdef __STRICT_BSD__
p=index(optarg, ':');
#else
p=strchr(optarg, ':');
#endif
if (p) {
(void)fprintf(stderr,
"%s: file name may not contain colons\n",
*argv);
exit(1);
}
#ifndef AUX
for (p=optarg;(c=(int)*(unsigned char *)p++)!=0;)
#ifdef NeXT
if ((c&~0x7f)!=0&&nsetomac[c]==32)
#else
if ((c&~0x7f)!=0&&iso1tomac[c]==32)
#endif
{
(void)fprintf(stderr,
"%s: invalid character(s) in file name\n", *argv);
exit(1);
}
#endif
hname=optarg;
break;
default:
goto usage;
}
if (argc-optind!=2) {
usage:
(void)fprintf(stderr,
"Usage:\n\t%s -r [-n name] in.flp out.image\n", *argv);
(void)fprintf(stderr,
"\t%s -m [-H out.image] [-n name] in.flp out.image.bin\n", *argv);
(void)fprintf(stderr,
"\t%s -s [-H out.image] [-n name] in.flp out.image.sgl\n", *argv);
#ifdef GENERATE_MACBINARY_III
(void)fputs("\t\t-r [Raw] Data Fork only\n\
\t\t\t(implied type='dImg' creator='dCpy')\n\
\t\t-m MacBinary III\n\
\t\t-s AppleSingle\n\
\t\t-H MacBinary/AppleSingle file name\n\
\t\t-n Name in disk image header\n", stderr);
#else
(void)fputs("\t\t-r [Raw] Data Fork only\n\
\t\t\t(implied type='dImg' creator='dCpy')\n\
\t\t-m MacBinary II\n\
\t\t-s AppleSingle\n\
\t\t-H MacBinary/AppleSingle file name\n\
\t\t-n Name in disk image header\n", stderr);
#endif
exit(1);
}
if (fmt<=0) {
(void)fprintf(stderr, "%s: specify one of -m, -r, or -s\n",
*argv);
exit(1);
}
if (hname&&fmt<2) {
(void)fprintf(stderr,
"%s: -H can't be specified with -r\n", *argv);
exit(1);
}
if (!named) {
#ifdef __STRICT_BSD__
b=rindex(argv[optind], '/');
#else
b=strrchr(argv[optind], '/');
#endif
if (!b) b=argv[optind];
else b++;
if ((c=strlen(b))>63) c=63;
p=(char *)imgh;
*p++=c;
while (c>0) {
if (*b=='.') {
b++;
*p++='\245';
if (--c<=0) break;
}
do {
if (*b==':') {
b++;
*p++='/';
}
else
#ifdef AUX
*p++= *b++;
#else
*(unsigned char *)p++=
#ifdef NeXT
nsetomac[*(unsigned char *)b++];
#else
iso1tomac[*(unsigned char *)b++];
#endif
#endif
} while (--c>0);
break;
/*NOTREACHED*/
}
}
if (!hname) {
#ifdef __STRICT_BSD__
b=rindex(argv[argc-1], '/');
#else
b=strrchr(argv[argc-1], '/');
#endif
if (!b) b=argv[argc-1];
else b++;
p=hbuf;
if ((c=strlen(b))>0) {
if (c>4&&((!strcmp(&b[c-4], ".bin"))||
!strcmp(&b[c-4], ".sgl"))) c-=4;
if (c>63) c=63;
do {
if (*b==':') {
b++;
*p++='/';
}
else *p++=*b++;
} while (--c>0);
}
*p='\0';
hname=hbuf;
}
p=argv[optind];
if ((*p!='-'||p[1]!='\0')&&!freopen(p, "r", stdin)) {
perror(p);
exit(1);
}
(void)fstat(fileno(stdin), &st);
if ((st.st_mode&S_IFMT)==S_IFDIR) {
(void)fprintf(stderr, "%s: input can't be a directory\n",
*argv);
exit(1);
}
#ifdef __STDC__
b=(char *)malloc(1474560u);
#else
b=(char *)malloc(1474560);
#endif
if (!b) {
(void)fprintf(stderr, "%s: malloc() failed!\n", *argv);
exit(1);
}
p=argv[argc-1];
if ((*p!='-'||p[1]!='\0')&&!freopen(p, "w", stdout)) {
perror(p);
exit(1);
}
s=0L;
n=0L;
p=b;
while ((c=getchar())!=EOF) {
if (n>=1474560L) break;
*p++=c;
n++;
s+=(unsigned long)c<<8;
if ((c=getchar())==EOF) break;
*p++=c;
n++;
s+=(unsigned long)c;
if (s&1) {
s>>=1;
s|=0x80000000L;
}
else {
s>>=1;
s&=0x7fffffffL;
}
}
imgh[72]=(s>>24)&0xff; /* dataChecksum */
imgh[73]=(s>>16)&0xff;
imgh[74]=(s>>8)&0xff;
imgh[75]=s&0xff;
switch ((long)n) {
case 1474560L: /* 1440K */
#ifdef NOTDEF
imgh[65]=0x16; /* dataSize+1 */
imgh[66]=0x80; /* dataSize+2 */
imgh[80]=0x03; /* diskFormat */
#endif
break;
case 737280L: /* 720K */
imgh[65]=0x0b; /* dataSize+1 */
imgh[66]=0x40; /* dataSize+2 */
imgh[80]=0x02; /* diskFormat */
break;
default:
(void)fprintf(stderr, "%s: input not 1440K or 720K\n", *argv);
exit(1);
break;
}
if (fmt>1) (void)sprintf((char *)&rsrcfork[301], "%08lX", s);
if (fmt==2) writembh(stdout, hname, sizeof imgh+n, 359L, st.st_mtime);
else if (fmt==3) {
writeash(stdout, hname, sizeof imgh+n, 359L,
st.st_mtime, st.st_atime);
#ifdef PACK1
(void)fwrite((char *)rsrcfork, 1, 359, stdout);
#else
(void)fwrite((char *)rsrcfork, 1, 360, stdout);
#endif
}
(void)fwrite((char *)imgh, sizeof imgh, 1, stdout);
(void)fwrite(b, 1, n, stdout);
if (fmt==2) {
c=128-sizeof imgh; do {
putc('\0', stdout);
} while (--c>0);
(void)fwrite((char *)rsrcfork, 1, 384, stdout);
}
(void)fflush(stdout);
if (ferror(stdout)) {
(void)fprintf(stderr, "%s: error writing output\n", *argv);
(void)fflush(stderr);
p=argv[argc-1];
if (*p!='-'||p[1]!='\0') (void)ftruncate(fileno(stdout), 0L);
exit(1);
}
exit(0);
}
/* Return offset from GMT */
#ifdef __STDC__
long gmtoff(long when)
#else
long gmtoff(when)
long when;
#endif
{
register struct tm *tm;
tm=localtime(&when);
#ifdef CUPERTINO_CENTRIC
return((tm->tm_isdst>0) ? -25200L : -28800L);
#else
#ifdef HAVE_TM_ZONE
return(tm->tm_gmtoff); /* BSD */
#else
#ifdef hpux
if (tm->tm_isdst<=0) return(-timezone);
/* the following is technically wrong, but works in the U.S. */
return(3600L-timezone);
#else /* !hpux */
return((tm->tm_isdst>0) ? -altzone : -timezone); /* SVR4 */
#endif /* !hpux */
#endif /* !HAVE_TM_ZONE */
#endif /* !CUPERTINO_CENTRIC */
}
/* See <URL:ftp://ftp.rocksoft.com/clients/rocksoft/papers/crc_v3.txt> */
#ifdef __STDC__
const
#endif
unsigned short crc_ccitt[256]={
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/* write MacBinary II header */
/* this is really a structure with misaligned elements, grr */
#ifdef __STDC__
void writembh(FILE *outf, const char *fname,
unsigned long dlen, unsigned long rlen, long mtime)
#else
void writembh(outf, fname, dlen, rlen, mtime)
FILE *outf;
char *fname;
unsigned long dlen, rlen;
long mtime;
#endif
{
register unsigned char *p;
register unsigned short crc;
register unsigned long when;
register unsigned char *e;
register int c;
#ifdef __STDC__
register const char *b;
#else
register char *b;
#endif
unsigned char mbh[128];
#ifdef USE_MEMSET
memset((void *)mbh, 0, sizeof mbh);
#else
bzero((char *)mbh, sizeof mbh);
#endif
b=fname;
if ((c=strlen(b))>63) c=63;
p= &mbh[1];
*p++=c;
while (c>0) {
if (*b=='.') {
b++;
*p++='\245';
if (--c<=0) break;
}
do {
#ifdef AUX
*p++= *b++;
#else
*(unsigned char *)p++=
#ifdef NeXT
nsetomac[*(unsigned char *)b++];
#else
iso1tomac[*(unsigned char *)b++];
#endif
#endif
} while (--c>0);
break;
/*NOTREACHED*/
}
p=mbh;
(void)strncpy((char *)&p[65], "dImgdCpy", 8);
#ifdef NOTDEF
/* my data fork is <16M */
p[83]=(dlen>>24)&255; /* data fork length */
#endif
p[84]=(dlen>>16)&255;
p[85]=(dlen>>8)&255;
p[86]=dlen&255;
#ifdef NOTDEF
/* my resource fork is <64K */
p[87]=(rlen>>24)&255; /* resource fork length */
#endif
p[88]=(rlen>>16)&255;
p[89]=(rlen>>8)&255;
p[90]=rlen&255;
when=(unsigned long)(mtime+2082844800L+gmtoff(mtime));
p[91]=(when>>24)&255; /* creation */
p[92]=(when>>16)&255;
p[93]=(when>>8)&255;
p[94]=when&255;
p[95]=(when>>24)&255; /* modification */
p[96]=(when>>16)&255;
p[97]=(when>>8)&255;
p[98]=when&255;
#ifdef GENERATE_MACBINARY_III
p[102]='m'; p[103]='B'; p[104]='I'; p[105]='N';
p[122]='\202';
#else
p[122]='\201';
#endif
p[123]='\201';
e=p+124;
/* crc computation adapted from mcvert */
crc=0;
do {
crc^=*p++<<8;
crc=((crc&255)<<8)^crc_ccitt[(crc>>8)&255];
} while (p<e);
*e++=(crc>>8)&255;
*e=crc&255;
(void)fwrite((char *)mbh, 1, sizeof mbh, outf);
}
static unsigned char asgl0[98]={
0x00, 0x05, 0x16, 0x00, /* magic */
0x00, 0x02, 0x00, 0x00, /* version */
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 6, /* entries */
0, 0, 0, 3, /* entryid=3L (Real Name) */
0x00, 0x00, 0x00, 0x62, /* offset */
0, 0, 0, 0, /* length */
0, 0, 0, 9, /* entryid=9L (Finder Info) */
0x00, 0x00, 0x00, 0x62, /* offset */
0, 0, 0, 32, /* length=32L */
0, 0, 0, 8, /* entryid=8L (File Dates Info) */
0x00, 0x00, 0x00, 0x82, /* offset */
0, 0, 0, 16, /* length=16L */
0, 0, 0, 4, /* entryid=4L (Comment) */
0x00, 0x00, 0x00, 0x92, /* offset */
0, 0, 0, 0, /* length */
0, 0, 0, 2, /* entryid=2L (Resource Fork) */
0x00, 0x00, 0x00, 0x92, /* offset */
0, 0, 0, 0, /* length */
0, 0, 0, 1, /* entryid=1L (Data Fork) */
0x00, 0x00, 0x00, 0x92, /* offset */
0, 0, 0, 0 /* length */
}, asgl1[48]={
'd', 'I', 'm', 'g', /* fdType */
'd', 'C', 'p', 'y', /* fdCreator */
0x01, 0x00, /* fdFlags */
0, 0, /* fdLocation.v */
0, 0, /* fdLocation.h */
0, 0, /* fdFldr */
0, 0, /* fdIconID */
0, 0, 0, 0, 0, 0, /* fdUnused */
0x80, /* fdScript */
0x00, /* fdXFlags */
0, 0, /* fdComment */
0, 0, 0, 0, /* fdPutAway */
0x4b, 0x6d, 0x0c, 0x00, /* creation */
0x4b, 0x6d, 0x0c, 0x00, /* modification */
0x4b, 0x6d, 0x0c, 0x00, /* backup */
0x4b, 0x6d, 0x0c, 0x00 /* access */
};
/* write AppleSingle header */
#ifdef __STDC__
void writeash(FILE *outf, const char *fname,
unsigned long dlen, unsigned long rlen, long mtime, long atime)
#else
void writeash(outf, fname, dlen, rlen, mtime, atime)
FILE *outf;
char *fname;
unsigned long dlen, rlen;
long mtime, atime;
#endif
{
#ifdef __STDC__
register const char *p;
#else
register char *p;
#endif
register int c;
register long off;
if ((c=strlen(fname))>63) c=63;
asgl0[37]=c;
#ifdef PACK1
off=(long)(98+c);
#else
/* not required, but not forbidden either */
off=(long)((101+c)&~3);
#endif
asgl0[44]=(unsigned char)((off>>8)&0xff);
asgl0[45]=(unsigned char)(off&0xff);
off+=32L;
asgl0[56]=(unsigned char)((off>>8)&0xff);
asgl0[57]=(unsigned char)(off&0xff);
off+=16L;
asgl0[68]=(unsigned char)((off>>8)&0xff);
asgl0[69]=(unsigned char)(off&0xff);
asgl0[80]=(unsigned char)((off>>8)&0xff);
asgl0[81]=(unsigned char)(off&0xff);
#ifdef NOTDEF
/* my resource fork is <64K */
asgl0[83]=(unsigned char)((rlen>>16)&0xff);
#endif
asgl0[84]=(unsigned char)((rlen>>8)&0xff);
asgl0[85]=(unsigned char)(rlen&0xff);
#ifdef PACK1
off+=rlen;
#else
#ifdef NOTDEF
off+=rlen+3L;
off&=~3L;
#else
off+=(rlen+3L)&~3L;
#endif
#endif
asgl0[92]=(unsigned char)((off>>8)&0xff);
asgl0[93]=(unsigned char)(off&0xff);
#ifdef NOTDEF
/* my data fork is <16M */
asgl0[94]=(unsigned char)((dlen>>24)&0xff);
#endif
asgl0[95]=(unsigned char)((dlen>>16)&0xff);
asgl0[96]=(unsigned char)((dlen>>8)&0xff);
asgl0[97]=(unsigned char)(dlen&0xff);
(void)fwrite((char *)asgl0, 1, sizeof asgl0, outf);
p=fname;
while (c>0) {
if (*p=='.') {
p++;
(void)fputc('\245', outf);
if (--c<=0) break;
}
do {
#ifdef AUX
(void)fputc(*p++, outf);
#else
#ifdef NeXT
(void)fputc((int)nsetomac[*(unsigned char *)p++],
outf);
#else
(void)fputc((int)iso1tomac[*(unsigned char *)p++],
outf);
#endif
#endif
} while (--c>0);
break;
/*NOTREACHED*/
}
#ifndef PACK1
switch (asgl0[37]&3) {
case 3:
(void)fputc('\0', outf);
/*FALL THROUGH*/
case 0:
(void)fputc('\0', outf);
/*FALL THROUGH*/
case 1:
(void)fputc('\0', outf);
/*FALL THROUGH*/
default:
break;
}
#endif
/* time offsets intended to be compatible with Dartmouth Fetch */
off=(unsigned long)(mtime-946684800L+gmtoff(mtime));
asgl1[36]=asgl1[32]=(unsigned char)((off>>24)&0xff);
asgl1[37]=asgl1[33]=(unsigned char)((off>>16)&0xff);
asgl1[38]=asgl1[34]=(unsigned char)((off>>8)&0xff);
asgl1[39]=asgl1[35]=(unsigned char)(off&0xff);
off=(unsigned long)(atime-946684800L+gmtoff(atime));
asgl1[44]=(unsigned char)((off>>24)&0xff);
asgl1[45]=(unsigned char)((off>>16)&0xff);
asgl1[46]=(unsigned char)((off>>8)&0xff);
asgl1[47]=(unsigned char)(off&0xff);
(void)fwrite((char *)asgl1, 1, sizeof asgl1, outf);
}
syntax highlighted by Code2HTML, v. 0.9.1