home *** CD-ROM | disk | FTP | other *** search
- From: dplatt@coherent.com (Dave Platt)
- Newsgroups: alt.sources
- Subject: [appletalk] MacBinary-to-CAP file converter
- Message-ID: <1990Jul27.035725.1421@math.lsa.umich.edu>
- Date: 27 Jul 90 03:57:25 GMT
-
- Archive-name: bin2cap/27-Jul-90
- Original-posting-by: dplatt@coherent.com (Dave Platt)
- Original-subject: MacBinary-to-CAP file converter
- Reposted-by: emv@math.lsa.umich.edu (Edward Vielmetti)
-
- [Reposted from comp.protocols.appletalk.
- Comments on this service to emv@math.lsa.umich.edu (Edward Vielmetti).]
-
- Well, I finally decided to get off of my rear end and write a utility
- which could convert a MacBinary file into CAP/Aufs format. By cutting
- and splicing portions of "cvt2cap", Aufs code, and the "macbin" program,
- I managed to get something which seems to work reasonably well (on my
- Sparcstation, at least).
-
- It lacks somewhat in its error checking capability (it doesn't verify
- the CRC in the MacBinary II header); it assumes MacBinary II format
- (which is mostly what one finds these days); and the source-code
- contains a fair bit of residue from its origin as part of three
- different programs, and could use some cleanup. Quite frankly, it's a
- quick and somewhat ugly hack.
-
- Nevertheless, it works. I'm sure I'm not the only CAP user who has been
- wishing for a utility of this sort... so, here it is. It's small, so
- I'm posting it here rather than going through comp.sources.whatever...
- may the Net Gods forgive me for my presumption.
-
- /*
- * bin2cap
- *
- * This program converts MacBinary files to CAP/aufs
- * format files.
- *
- * bin2cap [sourcefile]
- *
- * The specified source file (or the standard input if no source
- * file is specified) is read, verified to be in MacBinary format,
- * and used to create an Aufs-compatible file in the current working
- * directory. The original file is left unchanged.
- *
- * COPYRIGHT NOTICE
- *
- * Copyright 1990 by Dave Platt. All Rights Reserved.
- *
- * Permission is granted to any individual or institution to use, copy,
- * or redistribute this software so long as it is not sold for profit,
- * provided that this notice and the original copyright notices are
- * retained. Dave Platt makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * Portions of this code are based on the "cvt2cap" program by Paul
- * Campbell; on the Aufs file-server package by Charlie Kim et al; and
- * on the "macbin" program (author unknown to me). Relevant copyrights
- * are included herein.
- *
- * For portions derived from Aufs:
- *
- * Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University
- * in the City of New York.
- *
- * For portions derived from cvt2cap:
- *
- * Copyright (c) May 1988, Paul Campbell, All Rights Reserved.
- *
- * Permission is granted to any individual or institution to use, copy,
- * or redistribute this software so long as it is not sold for profit,
- * provided that this notice and the original copyright notices are
- * retained. Paul Campbell makes no representations about the
- * suitability of this software for any purpose. It is provided "as is"
- * without express or implied warranty.
- *
- * History:
- * 4/23/88 Paul Campbell, submitted to CAP distribution
- * 4/23/88 Charlie C. Kim, clean up and modify to work with
- * byte swapped machines
- * 7/26/90 Dave Platt, beaten about the head and shoulders with a stick
- * until it would eat MacBinary files rather than AppleSingle
- * or AppleDouble.
- *
- */
-
-
- #include <stdio.h>
- #include <ctype.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <netinet/in.h>
- #include <netat/appletalk.h>
- #include <netat/macfile.h>
-
- char *prog;
-
- struct macbinhdr {
- /* 000 */ char zero1;
- /* 001 */ char nlen;
- /* 002 */ char name[63];
- /* 065 */ char type[4];
- /* 069 */ char creator[4];
- /* 073 */ char flags;
- /* 074 */ char zero2;
- /* 075 */ char vert[2];
- /* 077 */ char horiz[2];
- /* 079 */ char folderID[2];
- /* 081 */ char protected;
- /* 082 */ char zero3;
- /* 083 */ char dflen[4];
- /* 087 */ char rflen[4];
- /* 091 */ char cdate[4];
- /* 095 */ char mdate[4];
- /* 099 */ char ilen[2];
- /* 101 */ char flags2;
- /* 102 */ char zero4[20];
- /* 122 */ char mbvers;
- /* 123 */ char minvers;
- /* 124 */ char crc[2];
- /* 126 */ char zero5[2];
- } header;
-
-
- char dir[] = "";
- char file[1025];
- char ename[1024],iname[1024];
-
- static char *hexdigits = "0123456789abcdef";
-
- FileInfo finfo;
- fileFinderInfo *finderInfo;
-
- FILE *fiopen();
- void EtoIName();
- int ENameLen();
-
- main(argc, argv)
- char **argv;
- {
- char *fin, *fout;
- FILE *f, *fd, *fx;
- register int i, j;
- int resource, data;
- u_long temp;
-
- bzero(&finfo, sizeof(finfo)); /* make sure clear first */
-
- prog = argv[0];
-
- if (argc > 2)
- {
- usage();
- }
-
- if (argc == 1)
- {
- f = stdin;
- }
- else
- {
- if ((f = fiopen(dir, NULL, argv[1], "r")) == NULL)
- {
- error("can't open input file %", argv[1]);
- }
- }
-
-
- /*
- * Read the header
- */
-
- if (fread(&header, sizeof header, 1, f) < 1)
- {
- error("could not read MacBinary header header");
- }
-
- if (header.zero1 != 0 || header.zero2 != 0 || header.nlen <= 0 ||
- header.nlen > 63)
- {
- error ("not a MacBinary file!");
- }
-
- bzero(ename, sizeof ename);
- strncpy(ename, header.name, header.nlen);
- if (ENameLen(ename) > 31)
- {
- error("encoded name > 31 characters");
- }
- EtoIName(ename, iname);
-
- finderInfo = (fileFinderInfo *) finfo.fi_fndr;
- bcopy(header.type, finderInfo->fdType, 4);
- bcopy(header.creator, finderInfo->fdCreator, 4);
- finderInfo->fdFlags = ((header.flags << 8) | header.flags2) & 0xf8fc;
-
- finfo.fi_magic1 = FI_MAGIC1;
- finfo.fi_version = FI_VERSION;
- finfo.fi_magic = FI_MAGIC;
- finfo.fi_bitmap = FI_BM_MACINTOSHFILENAME;
- finfo.fi_macfilename[0] = header.nlen;
- bcopy(header.name, finfo.fi_macfilename+1, header.nlen);
-
- fx = fiopen(dir, ".finderinfo/", iname, "w");
- if (fx == NULL)
- error("cannot create output finder info file '%s'", iname);
- if (fwrite(&finfo, sizeof(finfo), 1, fx) < 1)
- error("cannot write output finder info file '%s'", iname);
- fclose(fx);
-
- bcopy(header.dflen, &temp, sizeof temp);
- data = ntohl(temp);
-
- bcopy(header.rflen, &temp, sizeof temp);
- resource = ntohl(temp);
-
- fx = fiopen(dir, NULL, iname, "w");
- if (fx == NULL)
- error("cannot create output data file '%s'", iname);
- fcopy(fx, f, data);
- fclose(fx);
-
- if (resource > 0)
- {
- while ((data%128) != 0)
- {
- (void) fgetc(f);
- data++;
- }
-
- fx = fiopen(dir, ".resource/", iname, "w");
- if (fx == NULL)
- error("cannot create output resource file '%s'",
- iname);
- fcopy(fx, f, resource);
- fclose(fx);
- }
- }
-
- /*
- * open the file "dir""ext""file" with mode "mode"
- */
-
- FILE *
- fiopen(dir, ext, file, mode)
- char *dir, *ext, *file, *mode;
- {
- char name[1025];
-
- strcpy(name, dir);
- if (ext)
- strcat(name, ext);
- strcat(name, file);
- return(fopen(name, mode));
- }
-
- /*
- * print a nasty message
- */
-
- usage()
- {
- fprintf(stderr, "Usage: %s [macbinary-file]\n",
- prog);
- exit(1);
- }
-
- /*
- * copy length bytes from fin to fout
- */
-
- fcopy(fout, fin, length)
- FILE *fin, *fout;
- unsigned length;
- {
- char buffer[4096];
- register unsigned l;
-
- while (length > 0) {
- l = sizeof buffer;
- if (l > length)
- l = length;
- l = fread(buffer, 1, l, fin);
- if (l > 0) {
- if (fwrite(buffer, 1, l, fout) != l)
- error("error writing output file");
- } else break;
- length -= l;
- }
- }
-
- /*
- * print another nasty message and quit
- */
-
- error(s, a, b, c, d, e, f)
- char *s;
- {
- fprintf(stderr, "%s: ", prog);
- fprintf(stderr, s, a, b, c, d, e, f);
- fprintf(stderr, "\n");
- exit(2);
- }
-
- void
- EtoIName(en,inp)
- register byte *en; /* max is 31 or so */
- char *inp;
- {
- byte c; /* unsigned char */
- register char *in = inp;
- register int cnt = 0;
-
- while ((c = *en++) != '\0') {
- if (isascii(c) && !iscntrl(c) && isprint(c) && c != '/') {
- *in++ = c;
- cnt++;
- } else {
- /* must convert to */
- *in++ = ':'; /* : */
- *in++ = hexdigits[(c >> 4) & 0xf];
- *in++ = hexdigits[(c & 0xf)];
- cnt += 3;
- }
- }
- *in++ = '\0';
- }
-
- /*
- * Given an internal file name, compute the length of the external
- * file name
- */
- int
- ENameLen(in)
- register char *in;
- {
- register int len = 0;
- register char c;
- register char c2;
-
- while ((c = *in++) != '\0') {
- if (c != ':')
- len++;
- else {
- /* must convert to external form */
- if ((c = *in++) == '\0' || (c2 = *in++) == '\0') {
- len++;
- if (c != '\0')
- len++;
- break; /* done with while */
- }
- if (index(hexdigits,c) == NULL || index(hexdigits,c2) == NULL)
- len += 3;
- else
- len++;
- }
- }
- return(len);
- }
-