home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / source / macbincp.zoo / macbin2cap
Text File  |  1990-08-14  |  7KB  |  332 lines

  1.  
  2. /*
  3.  *    bin2cap
  4.  *
  5.  *    This program converts MacBinary files to CAP/aufs
  6.  *    format files.
  7.  *
  8.  *        bin2cap [sourcefile]
  9.  *
  10.  *      The specified source file (or the standard input if no source
  11.  *      file is specified) is read, verified to be in MacBinary format,
  12.  *      and used to create an Aufs-compatible file in the current working
  13.  *      directory.  The original file is left unchanged.
  14.  *
  15.  *    COPYRIGHT NOTICE
  16.  *
  17.  *      Copyright 1990 by Dave Platt.  All Rights Reserved.
  18.  *
  19.  *    Permission is granted to any individual or institution to use, copy,
  20.  *    or redistribute this software so long as it is not sold for profit,
  21.  *    provided that this notice and the original copyright notices are
  22.  *    retained.  Dave Platt makes no representations about the
  23.  *    suitability of this software for any purpose.  It is provided "as is"
  24.  *    without express or implied warranty.
  25.  *      
  26.  *      Portions of this code are based on the "cvt2cap" program by Paul
  27.  *      Campbell;  on the Aufs file-server package by Charlie Kim et al;  and
  28.  *      on the "macbin" program (author unknown to me).  Relevant copyrights
  29.  *      are included herein.
  30.  *
  31.  *      For portions derived from Aufs:
  32.  *
  33.  *      Copyright (c) 1986, 1987, 1988 by The Trustees of Columbia University
  34.  *      in the City of New York.
  35.  *
  36.  *      For portions derived from cvt2cap:
  37.  *    
  38.  *    Copyright (c) May 1988, Paul Campbell, All Rights Reserved.
  39.  *    
  40.  *    Permission is granted to any individual or institution to use, copy,
  41.  *    or redistribute this software so long as it is not sold for profit,
  42.  *    provided that this notice and the original copyright notices are
  43.  *    retained.  Paul Campbell makes no representations about the
  44.  *    suitability of this software for any purpose.  It is provided "as is"
  45.  *    without express or implied warranty.
  46.  *    
  47.  *  History:
  48.  *    4/23/88 Paul Campbell, submitted to CAP distribution
  49.  *    4/23/88 Charlie C. Kim, clean up and modify to work with
  50.  *            byte swapped machines
  51.  *    7/26/90 Dave Platt, beaten about the head and shoulders with a stick
  52.  *            until it would eat MacBinary files rather than AppleSingle
  53.  *            or AppleDouble.
  54.  *
  55.  */    
  56.  
  57.  
  58. #include <stdio.h>
  59. #include <ctype.h>
  60. #include <sys/types.h>
  61. #include <sys/stat.h>
  62. #include <netinet/in.h>
  63. #include <netat/appletalk.h>
  64. #include <netat/macfile.h>
  65.  
  66. char *prog;
  67.  
  68. struct macbinhdr {
  69. /* 000 */  char zero1;
  70. /* 001 */  char nlen;
  71. /* 002 */  char name[63];
  72. /* 065 */  char type[4];
  73. /* 069 */  char creator[4];
  74. /* 073 */  char flags;    
  75. /* 074 */  char zero2;    
  76. /* 075 */  char vert[2];
  77. /* 077 */  char horiz[2];
  78. /* 079 */  char folderID[2];
  79. /* 081 */  char protected;        
  80. /* 082 */  char zero3;        
  81. /* 083 */  char dflen[4];
  82. /* 087 */  char rflen[4];
  83. /* 091 */  char cdate[4];
  84. /* 095 */  char mdate[4];
  85. /* 099 */  char ilen[2];
  86. /* 101 */  char flags2;
  87. /* 102 */  char zero4[20];
  88. /* 122 */  char mbvers;
  89. /* 123 */  char minvers;
  90. /* 124 */  char crc[2];
  91. /* 126 */  char zero5[2];       
  92. } header;
  93.  
  94.     
  95. char dir[] = "";
  96. char file[1025];
  97. char ename[1024],iname[1024];
  98.  
  99. static char *hexdigits = "0123456789abcdef";
  100.  
  101. FileInfo finfo;
  102. fileFinderInfo *finderInfo;
  103.  
  104. FILE *fiopen();
  105. void EtoIName();
  106. int ENameLen();
  107.  
  108. main(argc, argv)
  109. char **argv;
  110. {
  111.     char *fin, *fout;
  112.     FILE *f, *fd, *fx;
  113.     register int i, j;
  114.     int resource, data;
  115.     u_long temp;
  116.  
  117.     bzero(&finfo, sizeof(finfo)); /* make sure clear first */
  118.  
  119.     prog = argv[0];
  120.  
  121.     if (argc > 2)
  122.       {
  123.         usage();
  124.       }
  125.  
  126.     if (argc == 1)
  127.       {
  128.         f = stdin;
  129.       }
  130.     else
  131.       {
  132.         if ((f = fiopen(dir, NULL, argv[1], "r")) == NULL)
  133.           {
  134.         error("can't open input file %", argv[1]);
  135.           }
  136.       }
  137.  
  138.  
  139.     /*
  140.      *    Read the header 
  141.      */
  142.  
  143.     if (fread(&header, sizeof header, 1, f) < 1)
  144.       {
  145.         error("could not read MacBinary header header");
  146.       }
  147.  
  148.     if (header.zero1 != 0 || header.zero2 != 0 || header.nlen <= 0 ||
  149.         header.nlen > 63)
  150.       {
  151.         error ("not a MacBinary file!");
  152.       }
  153.  
  154.     bzero(ename, sizeof ename);
  155.     strncpy(ename, header.name, header.nlen);
  156.     if (ENameLen(ename) > 31)
  157.       {
  158.         error("encoded name > 31 characters");
  159.       }
  160.     EtoIName(ename, iname);
  161.  
  162.     finderInfo = (fileFinderInfo *) finfo.fi_fndr;
  163.     bcopy(header.type, finderInfo->fdType, 4);
  164.     bcopy(header.creator, finderInfo->fdCreator, 4);
  165.     finderInfo->fdFlags = ((header.flags << 8) | header.flags2) & 0xf8fc;
  166.  
  167.     finfo.fi_magic1 = FI_MAGIC1;
  168.     finfo.fi_version = FI_VERSION;
  169.     finfo.fi_magic = FI_MAGIC;
  170.     finfo.fi_bitmap = FI_BM_MACINTOSHFILENAME;
  171.     finfo.fi_macfilename[0] = header.nlen;
  172.     bcopy(header.name, finfo.fi_macfilename+1, header.nlen);
  173.  
  174.     fx = fiopen(dir, ".finderinfo/", iname, "w");
  175.     if (fx == NULL)
  176.         error("cannot create output finder info file '%s'", iname);
  177.     if (fwrite(&finfo, sizeof(finfo), 1, fx) < 1)
  178.         error("cannot write output finder info file '%s'", iname);
  179.     fclose(fx);
  180.  
  181.     bcopy(header.dflen, &temp, sizeof temp);
  182.     data = ntohl(temp);
  183.  
  184.     bcopy(header.rflen, &temp, sizeof temp);
  185.     resource = ntohl(temp);
  186.  
  187.     fx = fiopen(dir, NULL, iname, "w");
  188.     if (fx == NULL)
  189.       error("cannot create output data file '%s'", iname);
  190.     fcopy(fx, f, data);
  191.     fclose(fx);
  192.  
  193.     if (resource > 0)
  194.       {
  195.         while ((data%128) != 0)
  196.           {
  197.         (void) fgetc(f);
  198.         data++;
  199.           }
  200.  
  201.         fx = fiopen(dir, ".resource/", iname, "w");
  202.         if (fx == NULL)
  203.           error("cannot create output resource file '%s'",
  204.             iname);
  205.         fcopy(fx, f, resource);
  206.         fclose(fx);
  207.       }
  208. }
  209.  
  210. /*
  211.  *    open the file "dir""ext""file" with mode "mode"
  212.  */
  213.  
  214. FILE *
  215. fiopen(dir, ext, file, mode)
  216. char *dir, *ext, *file, *mode;
  217. {
  218.     char name[1025];
  219.  
  220.     strcpy(name, dir);
  221.     if (ext)
  222.         strcat(name, ext);
  223.     strcat(name, file);
  224.     return(fopen(name, mode));
  225. }
  226.  
  227. /*
  228.  *    print a nasty message
  229.  */
  230.  
  231. usage()
  232. {
  233.     fprintf(stderr, "Usage: %s [macbinary-file]\n",
  234.             prog);
  235.     exit(1);
  236. }
  237.  
  238. /*
  239.  *    copy length bytes from fin to fout
  240.  */
  241.  
  242. fcopy(fout, fin, length)
  243. FILE *fin, *fout;
  244. unsigned length;
  245. {
  246.     char buffer[4096];
  247.     register unsigned l;
  248.  
  249.     while (length > 0) {
  250.       l = sizeof buffer;
  251.       if (l > length)
  252.         l = length;
  253.       l = fread(buffer, 1, l, fin);
  254.       if (l > 0) {
  255.         if (fwrite(buffer, 1, l, fout) != l)
  256.           error("error writing output file");
  257.       } else break;
  258.       length -= l;
  259.     }
  260. }
  261.  
  262. /*
  263.  *     print another nasty message and quit 
  264.  */
  265.  
  266. error(s, a, b, c, d, e, f)
  267. char *s;
  268. {
  269.     fprintf(stderr, "%s: ", prog);
  270.     fprintf(stderr, s, a, b, c, d, e, f);
  271.     fprintf(stderr, "\n");
  272.     exit(2);
  273. }
  274.  
  275. void
  276. EtoIName(en,inp)
  277. register byte *en;        /* max is 31 or so */
  278. char *inp;
  279. {
  280.   byte c;            /* unsigned char */
  281.   register char *in = inp;
  282.   register int cnt = 0;
  283.  
  284.   while ((c = *en++) != '\0') {
  285.     if (isascii(c) && !iscntrl(c) && isprint(c) && c != '/') {
  286.       *in++ = c;
  287.       cnt++;
  288.     } else {
  289.       /* must convert to */
  290.       *in++ = ':';            /* : */
  291.       *in++ = hexdigits[(c >> 4) & 0xf];
  292.       *in++ = hexdigits[(c & 0xf)];
  293.       cnt += 3;
  294.     }
  295.   }
  296.   *in++ = '\0';
  297. }
  298.  
  299. /*
  300.  * Given an internal file name, compute the length of the external
  301.  * file name
  302.  */
  303. int
  304. ENameLen(in)
  305. register char *in;
  306. {
  307.   register int len = 0;
  308.   register char c;
  309.   register char c2;
  310.  
  311.   while ((c = *in++) != '\0') {
  312.     if (c != ':')
  313.       len++;
  314.     else {
  315.       /* must convert to external form */
  316.       if ((c = *in++) == '\0' || (c2 = *in++) == '\0') {
  317.     len++;
  318.     if (c != '\0')
  319.       len++;
  320.     break;                /* done with while */
  321.       }
  322.       if (index(hexdigits,c) == NULL || index(hexdigits,c2) == NULL) 
  323.     len += 3;
  324.       else
  325.     len++;
  326.     }
  327.   }    
  328.   return(len);
  329. }    
  330.  
  331.  
  332.