home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / Tickle-4.0.sit.hqx / Tickle-4.0 / src / macbinary.c < prev    next >
Text File  |  1993-11-18  |  20KB  |  767 lines

  1.  
  2. /*
  3. ** This source code was written by Tim Endres
  4. ** Email: time@ice.com.
  5. ** USMail: 8840 Main Street, Whitmore Lake, MI  48189
  6. **
  7. ** Some portions of this application utilize sources
  8. ** that are copyrighted by ICE Engineering, Inc., and
  9. ** ICE Engineering retains all rights to those sources.
  10. **
  11. ** Neither ICE Engineering, Inc., nor Tim Endres, 
  12. ** warrants this source code for any reason, and neither
  13. ** party assumes any responsbility for the use of these
  14. ** sources, libraries, or applications. The user of these
  15. ** sources and binaries assumes all responsbilities for
  16. ** any resulting consequences.
  17. */
  18.  
  19. #pragma segment MacBinary
  20.  
  21. #include "tickle.h"
  22. #include "mb.h"
  23.  
  24. #define MAC_BINARY_BLK_SIZE        128
  25.  
  26. static char            hdrbuffer[MAC_BINARY_BLK_SIZE];
  27. static char            buffer[MAC_BINARY_BLK_SIZE];
  28.  
  29. long        unpack_long();
  30.  
  31. #ifdef TCLAPPL
  32.  
  33. DoMacBinary(direction)
  34. int        direction;
  35. {
  36. Point        mypoint;
  37. SFReply        inreply, outreply;
  38. SFTypeList    mytypes;
  39. short        inref, outref, myerr, num_types;
  40. F_BLK_PTR    hdr_ptr;
  41.  
  42.     if (direction == MAC_FILE) {
  43.         /* Convert MacBinary file into a Macintosh file. */
  44.         mypoint.h = mypoint.v = 75;
  45. #ifdef NEVER_DEFINED
  46.         mytypes[0] = (ResType)'MacB';
  47.         num_types = 1;
  48.         if (CheckOption())
  49. #endif
  50.             num_types = -1;
  51.  
  52.         MyGetFile(mypoint, "\pMacBinary File:", NULL, num_types, mytypes, NULL, &inreply);
  53.         if (inreply.good) {
  54.             SetVol(NULL, inreply.vRefNum);
  55.             myerr = FSOpen(inreply.fName, inreply.vRefNum, &inref);
  56.             if (myerr != noErr) {
  57.                 p2cstr(inreply.fName);
  58.                 message_alert("Error #%d opening file '%s'.", myerr, inreply.fName);
  59.                 }
  60.             else {
  61.                 memset(hdrbuffer, 0, MAC_BINARY_BLK_SIZE);
  62.                 UBegYield();
  63.                 myerr = extract_macbinary_header(inref, hdrbuffer);
  64.                 if (myerr != noErr) {
  65.                     message_alert("Error #%d reading MacBinary header information.", myerr);
  66.                     }
  67.                 else {
  68.                     hdr_ptr = (F_BLK_PTR) &hdrbuffer[0];
  69.                     MyPutFile(mypoint, "\pMacintosh File:", &hdr_ptr->nlen, NULL, &outreply);
  70.                     if (outreply.good) {
  71.                         SetFPos(inref, fsFromStart, 0);
  72.                         myerr = extract_macbinary(inref, outreply.vRefNum, outreply.fName);
  73.                         if (myerr != noErr) {
  74.                             message_alert("Error #%d extracting Macintosh file.", myerr);
  75.                             }
  76.                         else
  77.                             linef("MacBinary file converted to Macintosh file.");
  78.                         }
  79.                     }
  80.                 FSClose(inref);
  81.                 UEndYield();
  82.                 }
  83.             }
  84.         }
  85.     else {
  86.         /* Convert Macintosh file into a MacBinary file. */
  87.         mypoint.h = mypoint.v = 75;
  88.         MyGetFile(mypoint, "\pMacintosh File:", NULL, -1, mytypes, NULL, &inreply);
  89.         if (inreply.good) {
  90.             sprintf(temp_str, "%.*s.mb", inreply.fName[0], &inreply.fName[1]);
  91.             c2pstr(temp_str);
  92.             MyPutFile(mypoint, "\pMacBinary File:", temp_str, NULL, &outreply);
  93.             if (outreply.good) {
  94.                 SetVol(NULL, outreply.vRefNum);
  95.                 myerr = Create(outreply.fName, outreply.vRefNum, APPL_TYPE, (ResType)'MacB');
  96.                 if (myerr == dupFNErr)
  97.                     {
  98.                     p2cstr(outreply.fName);
  99.                     file_type(outreply.fName, (ResType)'MacB', APPL_TYPE);
  100.                     c2pstr(outreply.fName);
  101.                     }
  102.                 myerr = FSOpen(outreply.fName, outreply.vRefNum, &outref);
  103.                 if (myerr != noErr) {
  104.                     p2cstr(outreply.fName);
  105.                     message_alert("Error #%d opening MacBinary file '%s'.",
  106.                                     myerr, outreply.fName);
  107.                     }
  108.                 else {
  109.                     UBegYield();
  110.                     myerr = insert_macbinary(outref, inreply.fName, inreply.vRefNum, 0);
  111.                     if (myerr != noErr)
  112.                         message_alert("Error #%d converting Macintosh file to MacBinary.", myerr);
  113.                     else
  114.                         linef("Macintosh file converted to MacBinary file.");
  115.                     FSClose(outref);
  116.                     UEndYield();
  117.                     }
  118.                 }
  119.             }
  120.         }
  121.  
  122.     UInitCursor();
  123.     }
  124.  
  125. #endif /* TCLAPPL */
  126.  
  127.  
  128. insert_macbinary(outref, name, vrefnum, dirid)
  129. short        outref;
  130. char        *name;        /* Pascal String */
  131. short        vrefnum;
  132. long        dirid;
  133. {
  134. char        *ptr;
  135. HParamBlockRec    pb;
  136. int            i, blocks, residue;
  137. long        datalen, rsrclen, bytes;
  138. short        dataref, rsrcref, myerr, result = noErr;
  139. char        savevname[255];
  140. char        cfilename[255];
  141. short        savevref;
  142. F_BLK_PTR    the_hdr;
  143.  
  144.     GetVol(savevname, &savevref);
  145.     SetVol(NULL, vrefnum);
  146.     
  147.     strncpy(cfilename, &name[1], name[0]);
  148.     cfilename[name[0]] = '\0';
  149.     
  150.     pb.fileParam.ioCompletion = 0;
  151.     pb.fileParam.ioNamePtr = name;
  152.     pb.fileParam.ioVRefNum = vrefnum;
  153.     pb.fileParam.ioDirID = dirid;
  154.     pb.fileParam.ioFVersNum = 0;
  155.     pb.fileParam.ioFDirIndex = 0;
  156.     PBHGetFInfo(&pb, false);
  157.     if (pb.fileParam.ioResult != noErr) {
  158.         SysBeep(0);
  159.         UUDEBUG(0, "Could not get information about file '%s'. Error #%d.\n",
  160.                         cfilename, pb.fileParam.ioResult);
  161.         return pb.fileParam.ioResult;
  162.         }
  163.  
  164.     RotateCursor(32);
  165.     the_hdr = (F_BLK_PTR) &hdrbuffer[0];
  166.     memset(hdrbuffer, 0, MAC_BINARY_BLK_SIZE);
  167.     
  168.     for (ptr = &name[i = name[0]]; i>0; ptr--,i--)
  169.         if (*ptr == ':') {
  170.             *ptr = (char)( name[0] - (int)(ptr - &name[0]) );
  171.             break;
  172.             }
  173.     if (*ptr > 63) *ptr = (char) 63;
  174.     BlockMove(ptr, &the_hdr->nlen, *ptr + 1);
  175.     if (ptr != &name[0])
  176.         *ptr = ':';    /* Put it back */
  177.  
  178.     BlockMove((Ptr)&pb.fileParam.ioFlFndrInfo.fdLocation, the_hdr->location, sizeof(the_hdr->location));
  179.     BlockMove((Ptr)&pb.fileParam.ioFlFndrInfo.fdType, the_hdr->type, sizeof(the_hdr->type));
  180.     BlockMove((Ptr)&pb.fileParam.ioFlFndrInfo.fdCreator, the_hdr->creator, sizeof(the_hdr->creator));
  181.     the_hdr->protected = ((pb.fileParam.ioFlFndrInfo.fdFlags & 0x40) != 0) ? '\001' : '\0';
  182.     pack_long(pb.fileParam.ioFlLgLen, the_hdr->dflen);
  183.     pack_long(pb.fileParam.ioFlRLgLen, the_hdr->rflen);
  184.     pack_long(pb.fileParam.ioFlCrDat, the_hdr->cdate);
  185.     pack_long(pb.fileParam.ioFlMdDat, the_hdr->mdate);
  186.     the_hdr->zero1 = 0;
  187.     the_hdr->zero2 = 0;
  188.     the_hdr->zero3 = 0;
  189.  
  190.     datalen = pb.fileParam.ioFlLgLen;
  191.     rsrclen = pb.fileParam.ioFlRLgLen;
  192.     
  193.     RotateCursor(32);
  194.     bytes = MAC_BINARY_BLK_SIZE;
  195.     myerr = FSWrite(outref, &bytes, hdrbuffer);
  196.     if (myerr != noErr || bytes != MAC_BINARY_BLK_SIZE) {
  197.         SysBeep(0);
  198.         UUDEBUG(0, "Error #%d writing MacBinary header data.\n",
  199.                 ((myerr != noErr) ? myerr : writErr));
  200.         return ((myerr != noErr) ? myerr : writErr);
  201.         }
  202.  
  203.     RotateCursor(32);
  204.     DoYield();
  205.     if (datalen > 0) {
  206.         SetVol(NULL, vrefnum);
  207.         pb.ioParam.ioPermssn = fsRdPerm;
  208.         pb.ioParam.ioMisc = NULL;
  209.         pb.fileParam.ioDirID = dirid;
  210.         myerr = PBHOpen(&pb, false);
  211.         if (myerr != noErr) {
  212.             SetVol(NULL, savevref);
  213.             SysBeep(0);
  214.             UUDEBUG(0, "Could not open file '%s'. Error #%d.\n", cfilename, myerr);
  215.             result = pb.ioParam.ioResult;
  216.             }
  217.         else {
  218.             dataref = pb.ioParam.ioRefNum;
  219.             
  220.             blocks = datalen / MAC_BINARY_BLK_SIZE;
  221.             residue = datalen % MAC_BINARY_BLK_SIZE;
  222.             while (blocks-- && result == noErr) {
  223.                 RotateCursor(32);
  224.                 DoYield();
  225.                 bytes = MAC_BINARY_BLK_SIZE;
  226.                 myerr = FSRead(dataref, &bytes, buffer);
  227.                 if (myerr != noErr) {
  228.                     result = myerr;
  229.                     SysBeep(0);
  230.                     UUDEBUG(0, "Error #%d reading file '%s'. [D]\n", myerr, cfilename);
  231.                     }
  232.                 else {
  233.                     bytes = MAC_BINARY_BLK_SIZE;
  234.                     myerr = FSWrite(outref, &bytes, buffer);
  235.                     if (myerr != noErr) {
  236.                         result = myerr;
  237.                         SysBeep(0);
  238.                         UUDEBUG(0, "Error #%d writing to output file.\n", myerr);
  239.                         }
  240.                     }
  241.                 }
  242.             if (residue > 0 && result == noErr) {
  243.                 RotateCursor(32);
  244.                 DoYield();
  245.                 for (ptr=buffer,i=0; i<MAC_BINARY_BLK_SIZE; i++) *ptr++ = '\0';
  246.                 bytes = residue;
  247.                 myerr = FSRead(dataref, &bytes, buffer);
  248.                 if (myerr != noErr) {
  249.                     result = myerr;
  250.                     SysBeep(0);
  251.                     UUDEBUG(0, "Error #%d reading file '%s' [D].\n", myerr, cfilename);
  252.                     }
  253.                 else {
  254.                     bytes = MAC_BINARY_BLK_SIZE;
  255.                     myerr = FSWrite(outref, &bytes, buffer);
  256.                     if (myerr != noErr) {
  257.                         result = myerr;
  258.                         SysBeep(0);
  259.                         UUDEBUG(0, "Error #%d writing to output file.\n", myerr);
  260.                         }
  261.                     }
  262.                 }
  263.     
  264.             WatchCursorOn();
  265.             PBClose((ParmBlkPtr) &pb, false);
  266.             }
  267.         }
  268.  
  269.     RotateCursor(32);
  270.     if (rsrclen > 0 && result == noErr) {
  271.         SetVol(NULL, vrefnum);
  272.         pb.fileParam.ioDirID = dirid;
  273.         myerr = PBHOpenRF(&pb, false);
  274.         if (myerr != noErr) {
  275.             SetVol(NULL, savevref);
  276.             SysBeep(0);
  277.             UUDEBUG(0, "Could not open resource file '%s'. Error #%d\n", cfilename, myerr);
  278.             result = pb.ioParam.ioResult;
  279.             }
  280.         else {
  281.             rsrcref = pb.ioParam.ioRefNum;
  282.             
  283.             blocks = rsrclen / MAC_BINARY_BLK_SIZE;
  284.             residue = rsrclen % MAC_BINARY_BLK_SIZE;
  285.             while (blocks-- && result == noErr) {
  286.                 RotateCursor(32);
  287.                 DoYield();
  288.                 bytes = MAC_BINARY_BLK_SIZE;
  289.                 myerr = FSRead(rsrcref, &bytes, buffer);
  290.                 if (myerr != noErr) {
  291.                     result = myerr;
  292.                     SysBeep(0);
  293.                     UUDEBUG(0, "Error #%d reading file '%s'. [R]\n", myerr, cfilename);
  294.                     }
  295.                 else {
  296.                     bytes = MAC_BINARY_BLK_SIZE;
  297.                     myerr = FSWrite(outref, &bytes, buffer);
  298.                     if (myerr != noErr) {
  299.                         result = myerr;
  300.                         SysBeep(0);
  301.                         UUDEBUG(0, "Error #%d writing to output file.\n", myerr);
  302.                         }
  303.                     }
  304.                 }
  305.             if (residue > 0 && result == noErr) {
  306.                 RotateCursor(32);
  307.                 DoYield();
  308.                 for (ptr=buffer,i=0; i<MAC_BINARY_BLK_SIZE; i++) *ptr++ = '\0';
  309.                 bytes = residue;
  310.                 myerr = FSRead(rsrcref, &bytes, buffer);
  311.                 if (myerr != noErr) {
  312.                     SysBeep(0);
  313.                     UUDEBUG(0, "Error #%d reading file '%s'. [R]\n", myerr, cfilename);
  314.                     }
  315.                 else {
  316.                     bytes = MAC_BINARY_BLK_SIZE;
  317.                     myerr = FSWrite(outref, &bytes, buffer);
  318.                     if (myerr != noErr) {
  319.                         result = myerr;
  320.                         SysBeep(0);
  321.                         UUDEBUG(0, "Error #%d writing to output file.\n", myerr);
  322.                         }
  323.                     }
  324.                 }
  325.             
  326.             WatchCursorOn();
  327.             PBClose((ParmBlkPtr) &pb, false);
  328.             }
  329.         }
  330.  
  331.     UInitCursor();
  332.     SetVol(NULL, savevref);
  333.     
  334.     return result;
  335.     }
  336.  
  337.  
  338. extract_macbinary(inref, vrefnum, outfile)
  339. short        inref;
  340. short        vrefnum;
  341. char        *outfile;    /* P-String, If NULL, use header. */
  342. {
  343. char            *ptr;
  344. ParamBlockRec    pb;
  345. int                i, blocks, residue;
  346. long            datalen, rsrclen, bytes;
  347. short            dataref, rsrcref, myerr, result = noErr;
  348. char            name[256];
  349. F_BLK_PTR        the_hdr;
  350. char            savevname[255];
  351. char            cfilename[255];
  352. short            savevref;
  353.  
  354.     GetVol(savevname, &savevref);
  355.     SetVol(NULL, vrefnum);
  356.     
  357.     RotateCursor(32);
  358.     DoYield();
  359.  
  360.     the_hdr = (F_BLK_PTR) &hdrbuffer[0];
  361.     for (ptr=hdrbuffer,i=0; i<MAC_BINARY_BLK_SIZE; i++) *ptr++ = '\0';
  362.     bytes = MAC_BINARY_BLK_SIZE;
  363.     myerr = FSRead(inref, &bytes, hdrbuffer);
  364.     if (myerr != noErr) {
  365.         SysBeep(0);
  366.         UUDEBUG(0, "extract_macbinary: Error #%d reading header.\n", myerr);
  367.         return myerr;
  368.         }
  369.     
  370.     datalen = unpack_long(the_hdr->dflen);
  371.     rsrclen = unpack_long(the_hdr->rflen);
  372.     
  373.     if (outfile != NULL) {
  374.         BlockMove(outfile, name, outfile[0] + 1);
  375.         }
  376.     else {
  377.         BlockMove(the_hdr->name, name, the_hdr->name[0] + 1);
  378.         }
  379.     strncpy(cfilename, &name[1], name[0]);
  380.     cfilename[name[0]] = '\0';
  381.  
  382.     RotateCursor(32);
  383.     DoYield();
  384.  
  385.     pb.ioParam.ioCompletion = 0;
  386.     pb.ioParam.ioNamePtr = name;
  387.     pb.ioParam.ioVRefNum = vrefnum;
  388.     pb.ioParam.ioVersNum = 0;
  389.     pb.ioParam.ioPermssn = fsWrPerm;
  390.     pb.ioParam.ioMisc = NULL;
  391.  
  392.     for ( i = 'B' ; i <= 'Z' ; ) {
  393.         myerr = PBCreate(&pb, FALSE);        
  394.         if (myerr == dupFNErr) {
  395.             if (i == 'B') {
  396.                 name[++name[0]] = '-';
  397.                 name[++name[0]] = i;
  398.                 }
  399.             name[name[0]] = i++;
  400.             continue;
  401.             }
  402.         else
  403.             break;
  404.         }
  405.     
  406.     if (myerr != noErr) {
  407.         SysBeep(0);
  408.         UUDEBUG(0, "extract_macbinary: Error #%d creating '%s'.\n", myerr, cfilename);
  409.         return myerr;
  410.         }
  411.     
  412.     linef("Extracting Macintosh file '%s'...", cfilename);
  413.  
  414.     RotateCursor(32);
  415.     if (datalen > 0 && result == noErr) {
  416.         SetVol(NULL, vrefnum);
  417.         myerr = PBOpen(&pb, false);
  418.         if (myerr != noErr) {
  419.             SetVol(NULL, savevref);
  420.             SysBeep(0);
  421.             UUDEBUG(0, "Error #%d opening data fork of '%s'.\n", myerr, cfilename);
  422.             result = pb.ioParam.ioResult;
  423.             }
  424.         else {
  425.             dataref = pb.ioParam.ioRefNum;
  426.             blocks = datalen / MAC_BINARY_BLK_SIZE;
  427.             residue = datalen % MAC_BINARY_BLK_SIZE;
  428.             while (blocks-- && result == noErr) {
  429.                 RotateCursor(32);
  430.                 DoYield();
  431.                 bytes = MAC_BINARY_BLK_SIZE;
  432.                 myerr = FSRead(inref, &bytes, buffer);
  433.                 if (myerr != noErr) {
  434.                     SysBeep(0);
  435.                     UUDEBUG(0, "Error #%d reading input file.\n", myerr);
  436.                     result = myerr;
  437.                     }
  438.                 else {
  439.                     bytes = MAC_BINARY_BLK_SIZE;
  440.                     myerr = FSWrite(dataref, &bytes, buffer);
  441.                     if (myerr != noErr) {
  442.                         SysBeep(0);
  443.                         UUDEBUG(0, "Error #%d writing to file '%s'. [D]\n", myerr, cfilename);
  444.                         result = myerr;
  445.                         }
  446.                     }
  447.                 }
  448.             if (residue > 0 && result == noErr) {
  449.                 RotateCursor(32);
  450.                 DoYield();
  451.                 bytes = MAC_BINARY_BLK_SIZE;
  452.                 myerr = FSRead(inref, &bytes, buffer);
  453.                 if (myerr != noErr) {
  454.                     SysBeep(0);
  455.                     UUDEBUG(0, "Error #%d reading input file.\n", myerr);
  456.                     result = myerr;
  457.                     }
  458.                 else {
  459.                     bytes = residue;
  460.                     myerr = FSWrite(dataref, &bytes, buffer);
  461.                     if (myerr != noErr) {
  462.                         SysBeep(0);
  463.                         UUDEBUG(0, "Error #%d writing to file '%s'. [D]\n", myerr, cfilename);
  464.                         result = myerr;
  465.                         }
  466.                     }
  467.                 }
  468.     
  469.             WatchCursorOn();
  470.             PBClose(&pb, false);
  471.             }
  472.         }
  473.  
  474.     RotateCursor(32);
  475.     if (rsrclen > 0 && result == noErr) {
  476.         SetVol(NULL, vrefnum);
  477.         myerr = PBOpenRF(&pb, false);
  478.         if (myerr != noErr) {
  479.             UUDEBUG(0, "Error #%d opening resource fork of '%s'.\n", myerr, cfilename);
  480.             result = pb.ioParam.ioResult;
  481.             }
  482.         else {
  483.             rsrcref = pb.ioParam.ioRefNum;
  484.             blocks = rsrclen / MAC_BINARY_BLK_SIZE;
  485.             residue = rsrclen % MAC_BINARY_BLK_SIZE;
  486.             while (blocks-- && result == noErr) {
  487.                 RotateCursor(32);
  488.                 DoYield();
  489.                 bytes = MAC_BINARY_BLK_SIZE;
  490.                 myerr = FSRead(inref, &bytes, buffer);
  491.                 if (myerr != noErr) {
  492.                     UUDEBUG(0, "Error #%d reading input file.\n", myerr);
  493.                     result = myerr;
  494.                     }
  495.                 else {
  496.                     bytes = MAC_BINARY_BLK_SIZE;
  497.                     myerr = FSWrite(rsrcref, &bytes, buffer);
  498.                     if (myerr != noErr) {
  499.                         SysBeep(0);
  500.                         UUDEBUG(0, "Error #%d writing to file '%s'. [R]\n", myerr, cfilename);
  501.                         result = myerr;
  502.                         }
  503.                     }
  504.                 }
  505.             if (residue > 0 && result == noErr) {
  506.                 RotateCursor(32);
  507.                 DoYield();
  508.                 bytes = MAC_BINARY_BLK_SIZE;
  509.                 myerr = FSRead(inref, &bytes, buffer);
  510.                 if (myerr != noErr) {
  511.                     UUDEBUG(0, "Error #%d reading input file.\n", myerr);
  512.                     result = myerr;
  513.                     }
  514.                 else {
  515.                     bytes = residue;
  516.                     myerr = FSWrite(rsrcref, &bytes, buffer);
  517.                     if (myerr != noErr) {
  518.                         SysBeep(0);
  519.                         UUDEBUG(0, "Error #%d writing to file '%s'. [R]\n", myerr, cfilename);
  520.                         result = myerr;
  521.                         }
  522.                     }
  523.                 }
  524.     
  525.             WatchCursorOn();
  526.             PBClose(&pb, false);
  527.             }
  528.         }
  529.  
  530.     WatchCursorOn();
  531.     DoYield();
  532.     SetVol(NULL, vrefnum);
  533.     if (result == noErr) {
  534.         pb.fileParam.ioFDirIndex = 0;
  535.         myerr = PBGetFInfo(&pb, false);
  536.     
  537.         pb.fileParam.ioFlFndrInfo.fdType = unpack_long(the_hdr->type);
  538.         pb.fileParam.ioFlFndrInfo.fdCreator = unpack_long(the_hdr->creator);
  539.         pb.fileParam.ioFlFndrInfo.fdFlags |= (short) the_hdr->flags;
  540.         pb.fileParam.ioFlFndrInfo.fdLocation.h = 16;
  541.         pb.fileParam.ioFlFndrInfo.fdLocation.v = 16;
  542.         pb.fileParam.ioFlMdDat = unpack_long(the_hdr->mdate);
  543.         pb.fileParam.ioFlCrDat = unpack_long(the_hdr->cdate);
  544.         
  545.         myerr = PBSetFInfo(&pb, false);
  546.         if (myerr != noErr) {
  547.             SysBeep(0);
  548.             UUDEBUG(0, "Error #%d setting file info for '%s'.\n", myerr, cfilename);
  549.             result = myerr;
  550.             }
  551.         
  552.         DoYield();
  553.         UUDEBUG(0, "EXTRACTED <%s> via MacBinary\n", cfilename);
  554.         FlushVol(NULL, vrefnum);
  555.         }
  556.     else {
  557.         myerr = PBDelete(&pb, FALSE);
  558.         }
  559.  
  560.     SetVol(NULL, savevref);
  561.     return result;
  562.     }
  563.  
  564. extract_macbinary_header(inref, hdr_ptr)
  565. short        inref;
  566. char        *hdr_ptr;
  567. {
  568. long        bytes;
  569. short        myerr;
  570.  
  571.     bytes = MAC_BINARY_BLK_SIZE;
  572.     myerr = FSRead(inref, &bytes, (Ptr)hdr_ptr);
  573.     
  574.     return myerr;
  575.     }
  576.  
  577. pack_long(mylong, to)
  578. register long mylong;
  579. register unsigned char *to;
  580. {
  581.     *to++ = (unsigned char) (mylong >> 24) & 0x000000FF;
  582.     *to++ = (unsigned char) (mylong >> 16) & 0x000000FF;
  583.     *to++ = (unsigned char) (mylong >> 8) & 0x000000FF;
  584.     *to++ = (unsigned char) mylong & 0x000000FF;
  585.     }
  586.  
  587. long
  588. unpack_long(from)
  589. register unsigned char *from;
  590. {
  591. unsigned long    mylong;
  592.  
  593.     mylong = (unsigned long) *from++;
  594.     mylong = (mylong << 8) + (unsigned long) *from++;
  595.     mylong = (mylong << 8) + (unsigned long) *from++;
  596.     mylong = (mylong << 8) + (unsigned long) *from;
  597.  
  598.     return mylong;
  599.     }
  600.  
  601.  
  602. int
  603. Cmd_UnMacBinary(clientData, interp, argc, argv)
  604.     char        *clientData;
  605.     Tcl_Interp    *interp;
  606.     int            argc;
  607.     char        **argv;
  608.     {
  609.     short        wdrefnum;
  610.     int            result = TCL_OK, push_err;
  611.     char        outname[256];
  612.     char        pascal_name[256];
  613.     short        inref, myerr;
  614.     F_BLK_PTR    hdr_ptr;
  615.     FInfo        finfo;
  616.     extern int macintoshErr;
  617. #pragma unused (clientData)
  618.  
  619.     if (argc < 2 || argc > 3)
  620.         {
  621.         Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
  622.             " mbfilename ?macfilename?\"", (char *) NULL);
  623.         return TCL_ERROR;
  624.         }
  625.  
  626.     myerr = TclMac_CWDCreateWD(&wdrefnum);
  627.     if (myerr != noErr)
  628.         {
  629.         Tcl_AppendResult(interp, "could not create working directory - ",
  630.                             Tcl_MacGetError(interp, result), NULL);
  631.         return TCL_ERROR;
  632.         }
  633.     
  634.     push_err = TclMac_CWDPushVol();
  635.  
  636.     strcpy(pascal_name, argv[1]);
  637.     c2pstr(pascal_name);
  638.     myerr = FSOpen(pascal_name, wdrefnum, &inref);
  639.     if (myerr != noErr)
  640.         {
  641.         Tcl_AppendResult(interp, "error opening file \"",
  642.                             argv[1], "\" ", Tcl_MacGetError(interp, myerr), (char *) NULL);
  643.         result = TCL_ERROR;
  644.         }
  645.     else {
  646.         memset(hdrbuffer, 0, MAC_BINARY_BLK_SIZE);
  647.         UBegYield();
  648.         myerr = extract_macbinary_header(inref, hdrbuffer);
  649.         if (myerr != noErr)
  650.             {
  651.             Tcl_AppendResult(interp, "error reading MacBinary header info ",
  652.                                 Tcl_MacGetError(interp, myerr), (char *) NULL);
  653.             result = TCL_ERROR;
  654.             }
  655.         else
  656.             {
  657.             hdr_ptr = (F_BLK_PTR) &hdrbuffer[0];
  658.             if (argc > 2)
  659.                 {
  660.                 strcpy(outname, argv[2]);
  661.                 c2pstr(outname);
  662.                 }
  663.             else
  664.                 {
  665.                 BlockMove(&hdr_ptr->nlen, outname, hdr_ptr->nlen+1);
  666.                 }
  667.             
  668.             myerr = GetFInfo(outname, wdrefnum, &finfo);
  669. #ifdef NEVER_DEFINED
  670. /*
  671. ** UNDONE should warn and quit without a "-f" flag..
  672. */
  673.             if (myerr == noErr) /* File EXISTS!!! */
  674.                 outname[++outname[0]] = '1';
  675.             while (myerr == noErr)
  676.                 {
  677.                 /* File EXISTS!!! */
  678.                 outname[outname[0]]++;
  679.                 myerr = GetFInfo(outname, wdrefnum, &finfo);
  680.                 }
  681. #endif
  682.             
  683.             SetFPos(inref, fsFromStart, 0);
  684.             myerr = extract_macbinary(inref, wdrefnum, outname);
  685.             if (myerr != noErr)
  686.                 {
  687.                 p2cstr(outname);
  688.                 Tcl_AppendResult(interp, "error extracting Macintosh file \"",
  689.                                     outname, "\" ", Tcl_MacGetError(interp, myerr), NULL);
  690.                 result = TCL_ERROR;
  691.                 }
  692.             }
  693.         
  694.         FSClose(inref);
  695.         UEndYield();
  696.         }
  697.         
  698.     if (push_err == noErr)
  699.         TclMac_CWDPopVol();
  700.     
  701.     TclMac_CWDDisposeWD(wdrefnum);
  702.  
  703.     UInitCursor();
  704.     return result;
  705.     }
  706.  
  707. #pragma segment AppleEvent
  708.  
  709. AEUnMacBinary(theFSS)
  710. FSSpec        *theFSS;
  711. {
  712. short        wdrefnum;
  713. int            result;
  714. char        outname[256];
  715. short        inref, myerr;
  716. F_BLK_PTR    hdr_ptr;
  717. FInfo        finfo;
  718.  
  719.     Feedback("AEUnMacBinary: MacBinary: UnMacBinary '%.*s'",
  720.                 theFSS->name[0], &theFSS->name[1]);
  721.     
  722.  
  723.     result = OpenWD(theFSS->vRefNum, theFSS->parID, 'ERIK', &wdrefnum);
  724.     if (result == noErr) {
  725.         myerr = FSOpen(theFSS->name, wdrefnum, &inref);
  726.         if (myerr != noErr) {
  727.             Feedback("AEUnMacBinary: MacBinary: Error #%d opening '%.*s'.",
  728.                             myerr, theFSS->name[0], &theFSS->name[1]);
  729.             }
  730.         else {
  731.             memset(hdrbuffer, 0, MAC_BINARY_BLK_SIZE);
  732.             UBegYield();
  733.             myerr = extract_macbinary_header(inref, hdrbuffer);
  734.             if (myerr != noErr) {
  735.                 Feedback("Error #%d reading MacBinary header information.", myerr);
  736.                 }
  737.             else {
  738.                 hdr_ptr = (F_BLK_PTR) &hdrbuffer[0];
  739.                 BlockMove(&hdr_ptr->nlen, outname, hdr_ptr->nlen+1);
  740.                 myerr = GetFInfo(outname, wdrefnum, &finfo);
  741.                 if (myerr == noErr) /* File EXISTS!!! */
  742.                     outname[++outname[0]] = '1';
  743.                 while (myerr == noErr) {
  744.                     /* File EXISTS!!! */
  745.                     outname[outname[0]]++;
  746.                     myerr = GetFInfo(outname, wdrefnum, &finfo);
  747.                     }
  748.                 
  749.                 SetFPos(inref, fsFromStart, 0);
  750.                 myerr = extract_macbinary(inref, wdrefnum, outname);
  751.                 if (myerr != noErr) {
  752.                     Feedback("Error #%d extracting Macintosh file '%.*s'.",
  753.                                 myerr, outname[0], &outname[1]);
  754.                     }
  755.                 else
  756.                     Feedback("MacBinary '%.*s' converted to Macintosh '%.*s'.",
  757.                             theFSS->name[0], &theFSS->name[1], outname[0], &outname[1]);
  758.                 }
  759.             
  760.             FSClose(inref);
  761.             UEndYield();
  762.             }
  763.         }
  764.         
  765.     UInitCursor();
  766.     }
  767.