home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / Libraries / HQX 1.0 / example / hqxtool.c < prev    next >
Encoding:
C/C++ Source or Header  |  1997-07-05  |  6.5 KB  |  230 lines  |  [TEXT/MPS ]

  1. /* file hqxtool.c 
  2.     BinHex decoder/encoder routines, example MPW Tool.
  3.     Copyright (c) 1995, 1996, 1997 by John Montbriand.  All Rights Reserved.
  4.     Permission hereby granted for public use.
  5.         Distribute freely in areas where the laws of copyright apply.
  6.     USE AT YOUR OWN RISK.
  7.     DO NOT DISTRIBUTE MODIFIED COPIES.
  8.     Comments/questions/postcards* to the author at the address:
  9.       John Montbriand
  10.       P.O. Box. 1133
  11.       Saskatoon Saskatchewan Canada
  12.       S7K 3N2
  13.     or by email at:
  14.       tinyjohn@sk.sympatico.ca
  15.     *if you mail a postcard, then I will provide you with technical support
  16.     regarding questions you may have about this file.
  17. */
  18.  
  19. #include <Types.h>
  20. #include <QuickDraw.h>
  21. #include <Windows.h>
  22. #include <Dialogs.h>
  23. #include <Gestalt.h>
  24. #include <TextUtils.h>
  25. #include <Errors.h>
  26. #include <Memory.h>
  27. #include <strings.h>
  28. #include <ErrMgr.h>
  29. #include <StdIO.h>
  30. #include <PLStringFuncs.h>
  31. #include <string.h>
  32. #include <CursorCtl.h>
  33.  
  34. #include "hqx.h"
  35.  
  36. FILE *gDestFile, *gSrcFile;
  37. QDGlobals qd;
  38. FSSpec targetfile;
  39. Boolean replace_names, target_exists;
  40.  
  41.  
  42. static OSErr MySink(void* buffer, long count, long param) {
  43.     SpinCursor(16);
  44.     fwrite(buffer, count, 1, gDestFile);
  45.     return noErr;
  46. }
  47.  
  48. static OSErr MySource(void* buffer, long *count, long param) {
  49.     SpinCursor(16);
  50.     *count =  fread(buffer, 1, *count, gSrcFile);
  51.     return noErr;
  52. }
  53.  
  54. static char** GetFullPath(StringPtr objectname, short vol, long dir) {
  55.     Handle h;
  56.     CInfoPBRec cat;
  57.     Str255 separator;
  58.     Str63 name;
  59.     long response;
  60.     Boolean haveAUX;
  61.     h = NewHandle(0);
  62.     if (objectname != NULL) PtrToXHand(objectname+1, h, objectname[0]);
  63.     haveAUX = (Gestalt(gestaltAUXVersion, &response) == noErr);
  64.     PLstrcpy(separator, haveAUX ? "\p/" : "\p:");
  65.     cat.hFileInfo.ioNamePtr = name;
  66.     cat.hFileInfo.ioVRefNum = vol;
  67.     cat.hFileInfo.ioFlParID = dir;
  68.     cat.hFileInfo.ioFDirIndex = -1;
  69.     do {    cat.hFileInfo.ioDirID = cat.hFileInfo.ioFlParID;
  70.         if (PBGetCatInfoSync(&cat) != noErr) break;
  71.         Munger(h, 0, NULL, 0, separator+1, separator[0]);
  72.         Munger(h, 0, NULL, 0, name+1, name[0]);
  73.     } while (cat.hFileInfo.ioDirID != 2);
  74.     return (char**) h;
  75. }
  76.  
  77. static OSErr MyNameFilter(StringPtr name, short *vol, long *dir, long param) {
  78.     FInfo info;
  79.     if (target_exists) {
  80.         PLstrcpy(name, targetfile.name);
  81.         *vol = targetfile.vRefNum;
  82.         *dir = targetfile.parID;
  83.     }
  84.     if (replace_names) return noErr;
  85.     if (HGetFInfo(*vol, *dir, name, &info) == noErr) {
  86.         char** pathname;
  87.         Str255 tname;
  88.         long n;
  89.         if ((pathname = GetFullPath(name, *vol, *dir)) != NULL) {
  90.             n = GetHandleSize((Handle) pathname);
  91.             if (n > 255) n = 255;
  92.             tname[0] = n;
  93.             BlockMoveData(*pathname, tname+1, n);
  94.             ParamText(tname, NULL, NULL, NULL);
  95.             DisposeHandle((Handle) pathname);
  96.         } else ParamText(name, NULL, NULL, NULL);
  97.         InitCursor();
  98.         if (Alert(129, NULL) == ok) {
  99.             return HDelete(*vol, *dir, name);
  100.         } else return userCanceledErr;
  101.     }
  102.     return noErr;
  103. }
  104.  
  105. #define kInputBufferSize (8*1024)
  106. #define kOutputBufferSize (8*1024)
  107.  
  108. int main(long argc, char** argv) {
  109.     long i;
  110.     OSErr err;
  111.     FSSpec src;
  112.     char* dst;
  113.     Str255 name;
  114.     Boolean srcexists, decodecomplete;
  115.     char *input_buffer, *output_buffer;
  116.     
  117.     InitGraf(&qd.thePort);
  118.     
  119.     dst = NULL;
  120.     i = 1;
  121.     gSrcFile = NULL;
  122.     replace_names = target_exists = false;
  123.     srcexists = false;
  124.     decodecomplete = false;
  125.     input_buffer = output_buffer = NULL;
  126.     
  127.     if (argc == 1) {
  128.         fprintf(stderr, "# %s, binhex tool.\n", argv[0]);
  129.         fprintf(stderr, "# %s variants:\n", argv[0]);
  130.         fprintf(stderr, "#  -y avoids replace alert in decoding.\n");
  131.         fprintf(stderr, "#  %s [-y] -d file -- decode the binhex file\n", argv[0]);
  132.         fprintf(stderr, "#  %s [-y] -d file as newname -- decode the binhex file to newname\n", argv[0]);
  133.         fprintf(stderr, "#  %s file > file  -- encode file to stdout\n", argv[0]);
  134.         fprintf(stderr, "#  %s, file -o file -- encode file to filename\n", argv[0]);
  135.         return 0;
  136.     }
  137.  
  138.     while (i < argc) {
  139.         if (strcmp(argv[i], "-y") == 0) {
  140.             replace_names = true;
  141.             i += 1;
  142.         } else if (strcmp(argv[i], "-d") == 0) {
  143.             char *headerstring = "(This file must be converted with BinHex 4.0)";
  144.             if (i+1 >= argc) {
  145.                 fprintf(stderr, "#%s, parameters expected for -d\n", argv[0]);
  146.                 return 1;
  147.             }
  148.             if (output_buffer == NULL) {
  149.                 output_buffer = (char*) NewPtr(kOutputBufferSize);
  150.                 if ((err = MemError()) != noErr) goto misc_abort;
  151.             }
  152.             gSrcFile = fopen(argv[i+1], "r");
  153.             if (gSrcFile == NULL) { err = fnfErr; goto misc_abort; }
  154.             setvbuf(gSrcFile, output_buffer, _IOFBF, kOutputBufferSize);
  155.             if ((i+2 < argc) && strcmp(argv[i+2], "as") == 0) {
  156.                 if (i+3 >= argc) {
  157.                     fprintf(stderr, "#%s, name expected for -d %s as...\n", argv[0], argv[i+1]);
  158.                     return 1;
  159.                 }
  160.                 err = FSMakeFSSpec(0, 0, c2pstr(strcpy((char*) name, argv[i+3])), &targetfile);
  161.                 if (err == fnfErr) err = noErr;
  162.                 if (err != noErr) goto misc_abort;
  163.                 target_exists = true;
  164.                 err = HQXDecode(MySource, MyNameFilter, replace_names, true, 0);
  165.                 if (err != noErr) goto misc_abort;
  166.                 i += 4;
  167.             } else {
  168.                 err = HQXDecode(MySource, MyNameFilter, replace_names, true, 0);
  169.                 if (err != noErr) goto misc_abort;
  170.                 i += 2;
  171.             }
  172.             fclose(gSrcFile);
  173.             DisposePtr((Ptr) output_buffer);
  174.             output_buffer = NULL;
  175.             gSrcFile = NULL;
  176.             decodecomplete = true;
  177.         } else if (strcmp(argv[i], "-o") == 0) {
  178.             if (i+1 >= argc) {
  179.                 fprintf(stderr, "#%s, parameters expected for -o\n", argv[0]);
  180.                 return 1;
  181.             }
  182.             dst = argv[i+1];
  183.             i += 2;
  184.         } else if (!srcexists) {
  185.             err = FSMakeFSSpec(0, 0, c2pstr(strcpy((char*)name, argv[i])), &src);
  186.             if (err != noErr) goto misc_abort;
  187.             srcexists = true;
  188.             i += 1;
  189.         } else {
  190.             fprintf(stderr, "#%s, unknown parameter '%s'\n", argv[0], argv[i]);
  191.             return 1;
  192.         }
  193.     }
  194.  
  195.     if (decodecomplete) return 0;
  196.     
  197.     input_buffer = (char*) NewPtr(kInputBufferSize);
  198.     if ((err = MemError()) != noErr) goto misc_abort;
  199.     if (srcexists) {
  200.         if (dst == NULL) {
  201.             gDestFile = stdout;
  202.             setvbuf(gDestFile, input_buffer, _IOFBF, kInputBufferSize);
  203.             err = HQXEncode(src.name, src.vRefNum, src.parID, MySink, 0);
  204.             if (err != noErr) goto misc_abort;
  205.         } else {
  206.             gDestFile = fopen(dst, "w");
  207.             setvbuf(gDestFile, input_buffer, _IOFBF, kInputBufferSize);
  208.             err = HQXEncode(src.name, src.vRefNum, src.parID, MySink, 0);
  209.             fclose(gDestFile);
  210.             if (err != noErr) goto misc_abort;
  211.         }
  212.     } else {
  213.         fprintf(stderr, "#%s, no source file specified\n", argv[0], argv[i]);
  214.         return 1;
  215.     }
  216.     
  217.     return 0;
  218.     
  219. misc_abort:
  220.     if (gSrcFile != NULL) fclose(gSrcFile);
  221.     if (output_buffer != NULL) DisposePtr((Ptr) output_buffer);
  222.     if (input_buffer != NULL) DisposePtr((Ptr) input_buffer);
  223.     if (err == userCanceledErr) return 1;
  224.     fprintf(stderr, "# %s aborted.\n# %s\n", argv[0], GetSysErrText(err, (char*) name));
  225.     return 2;
  226. }
  227.  
  228. /* end of file hqxtool.c */
  229.  
  230.