/* 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 */ #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 #else #include #ifdef __STRICT_BSD__ #include #else #include #endif #ifndef __tm_gmtoff /* compensate for GNU/Linux lossage */ #define __tm_gmtoff tm_gmtoff #endif #include #include #include #include #include #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 * * 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 */ #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>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); }