home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / HEXBIN / hexbin.c < prev    next >
C/C++ Source or Header  |  1996-02-01  |  8KB  |  378 lines

  1. #ifdef TYPES_H
  2. #include <sys/types.h>
  3. #endif /* TYPES_H */
  4.  
  5. #ifndef OSK
  6. #include <sys/stat.h>
  7. #else
  8. #include "/dd/blarsdefs/sys/stat.h"
  9. #endif
  10.  
  11. #include "globals.h"
  12. #include "crc.h"
  13. #include "readline.h"
  14. #include "../util/masks.h"
  15. #include "../util/util.h"
  16. #include "../util/patchlevel.h"
  17. #include "../fileio/wrfile.h"
  18. #include "../fileio/wrfileopt.h"
  19. #include "../fileio/machdr.h"
  20. #include "../fileio/kind.h"
  21.  
  22. #ifndef OSK
  23. #include "../util/curtime.h"
  24. #else
  25. #define TIMEDIFF 0x7c25b080
  26. #endif
  27.  
  28. #include "hexbin.h"
  29.  
  30. #define LOCALOPT    "ilvcn:qVH"
  31.  
  32. extern void exit();
  33. extern void backtrans();
  34. #ifdef DL
  35. extern void dl();
  36. #endif /* DL */
  37. #ifdef HECX
  38. extern void hecx();
  39. #endif /* HECX */
  40. #ifdef HQX
  41. extern void hqx();
  42. #endif /* HQX */
  43. #ifdef MU
  44. extern void mu();
  45. #endif /* MU */
  46.  
  47. static void usage();
  48. static void do_files();
  49. static int find_header();
  50.  
  51. static char options[128];
  52.  
  53. int main(argc, argv)
  54. int argc;
  55. char **argv;
  56. {
  57.     char *filename;
  58.     char macname[32];
  59.     extern int optind;
  60.     extern char *optarg;
  61.     int errflg;
  62.     int c;
  63.  
  64.     set_wrfileopt(0);
  65.     (void)strcat(options, get_wrfileopt());
  66.     (void)strcat(options, LOCALOPT);
  67.     errflg = 0;
  68.     filename = "";
  69.     macname[0] = 0;
  70.  
  71.     while((c = getopt(argc, argv, options)) != EOF) {
  72.     if(!wrfileopt((char)c)) {
  73.         switch(c) {
  74.         case 'l':
  75.         listmode++;
  76.         break;
  77.         case 'v':
  78.         verbose++;
  79.         break;
  80.         case 'i':
  81.         info_only++;
  82.         break;
  83.         case 'c':
  84.         uneven_lines++;
  85.         break;
  86.         case 'n':
  87.         backtrans(macname, optarg);
  88.         break;
  89.         case '?':
  90.         errflg++;
  91.         break;
  92.         case 'H':
  93.         give_wrfileopt();
  94.         (void)fprintf(stderr, "Hexbin specific options:\n");
  95.         (void)fprintf(stderr,
  96.             "-i:\tgive information only, do not convert\n");
  97.         (void)fprintf(stderr, "-l:\tgive listing\n");
  98.         (void)fprintf(stderr,
  99.             "-v:\tgive verbose listing, including lines skipped\n");
  100.         (void)fprintf(stderr,
  101.             "-c:\tdo not check for equal line lengths\n");
  102.         (void)fprintf(stderr, "-n nm:\tname to be generated\n");
  103.         (void)fprintf(stderr,
  104.             "-V:\tgive information about this version\n");
  105.         (void)fprintf(stderr, "-H:\tthis message\n");
  106.         (void)fprintf(stderr, "Default is silent conversion\n");
  107.         exit(0);
  108.         case 'V':
  109.         (void)fprintf(stderr, "Version %s, ", VERSION);
  110.         (void)fprintf(stderr, "patchlevel %d", PATCHLEVEL);
  111.         (void)fprintf(stderr, "%s.\n", get_mina());
  112. #ifdef OSK
  113.         (void)fprintf(stderr, "OSK Port by Dean Leiber\n\n");
  114. #endif
  115.         (void)fprintf(stderr, "Hexified files recognized:\n");
  116. #ifdef DL
  117.         (void)fprintf(stderr, "\tDownload (.dl)\n");
  118. #endif /* DL */
  119. #ifdef HECX
  120.         (void)fprintf(stderr, "\tBinHex 2.0 (.hex)\n");
  121.         (void)fprintf(stderr, "\tBinHex 3.0 (.hcx)\n");
  122. #endif /* HECX */
  123. #ifdef HQX
  124.         (void)fprintf(stderr, "\tBinHex 4.0 (.hqx)\n");
  125. #endif /* HQX */
  126. #ifdef MU
  127.         (void)fprintf(stderr, "\tUUTool (.mu)\n");
  128. #endif /* MU */
  129.         exit(0);
  130.         }
  131.     }
  132.     }
  133.     if(errflg) {
  134.     usage();
  135.     exit(1);
  136.     }
  137.     if(info_only || verbose) {
  138.     listmode++;
  139.     }
  140.  
  141.     do {
  142.     if(optind == argc) {
  143.         filename = "-";
  144.     } else {
  145.         filename = argv[optind];
  146.         optind++;
  147. #ifdef SCAN
  148.         do_idf(filename, UNIX_NAME);
  149. #endif /* SCAN */
  150.     }
  151.     do_files(filename, macname);
  152.     } while(optind < argc);
  153.     exit(0);
  154.     /* NOTREACHED */
  155. }
  156.  
  157. static char *extensions[] = {
  158. #ifdef DL
  159.     ".dl",
  160. #endif /* DL */
  161. #ifdef HECX
  162.     ".hex",
  163.     ".Hex",
  164.     ".hcx",
  165.     ".Hcx",
  166. #endif /* HECX */
  167. #ifdef HQX
  168.     ".hqx",
  169.     ".Hqx",
  170. #endif /* HQX */
  171. #ifdef MU
  172.     ".mu",
  173. #endif /* MU */
  174.     "",
  175.     NULL
  176. };
  177.  
  178. static void do_files(filename, macname)
  179. char *filename;    /* input file name -- extension optional */
  180. char *macname;    /* name to use on the mac side of things */
  181. {
  182.     char namebuf[256];
  183.     char **ep;
  184.     struct stat stbuf;
  185.     long curtime;
  186.     int qformat;
  187.     int again;
  188.  
  189.     if(filename[0] == '-') {
  190.     ifp = stdin;
  191.     filename = "stdin";
  192.     } else {
  193.     /* find input file and open it */
  194.     for(ep = extensions; *ep != NULL; ep++) {
  195.         (void)sprintf(namebuf, "%s%s", filename, *ep);
  196.         if(stat(namebuf, &stbuf) == 0) {
  197.         break;
  198.         }
  199.     }
  200.     if(*ep == NULL) {
  201.         perror(namebuf);
  202.         exit(1);
  203.     }
  204.     ifp = fopen(namebuf, "r");
  205.     if(ifp == NULL) {
  206.         perror(namebuf);
  207.         exit(1);
  208.     }
  209.     }
  210.     again = 0;
  211. nexttry:
  212.     if(ifp == stdin) {
  213.     curtime = (long)time((time_t *)0) + TIMEDIFF;
  214.     mh.m_createtime = curtime;
  215.     mh.m_modifytime = curtime;
  216.     } else {
  217.     mh.m_createtime = stbuf.st_mtime + TIMEDIFF;
  218.     mh.m_modifytime = stbuf.st_mtime + TIMEDIFF;
  219.     }
  220.     qformat = find_header(again); /* eat mailer header &cetera, intuit format */
  221.  
  222.     switch (qformat) {
  223. #ifdef DL
  224.     case form_dl:
  225.     dl(macname, filename);
  226.     break;
  227. #endif /* DL */
  228. #ifdef HECX
  229.     case form_hecx:
  230.     hecx(macname, filename);
  231.     break;
  232. #endif /* HECX */
  233. #ifdef HQX
  234.     case form_hqx:
  235.     hqx(macname);
  236.     again = 1;
  237.     goto nexttry;
  238. #endif /* HQX */
  239. #ifdef MU
  240.     case form_mu:
  241.     mu(macname);
  242.     again = 1;
  243.     goto nexttry;
  244. #endif /* MU */
  245.     default:
  246.     break;
  247.     }
  248.     (void)fclose(ifp);
  249. }
  250.  
  251. /* eat characters until header detected, return which format */
  252. static int find_header(again)
  253. int again;
  254. {
  255.     int c, dl_start, llen;
  256.     char *cp;
  257.     char header[INFOBYTES];
  258.     int ds, rs;
  259.  
  260.     if(again && was_macbin) {
  261.     while(to_read-- > 0) {
  262.         c = fgetc(ifp);
  263.     }
  264.     }
  265.     was_macbin = 0;
  266.     c = fgetc(ifp);
  267.     (void)ungetc(c, ifp);
  268.     if(c == 0) {
  269.     was_macbin = 1;
  270.     if(fread(header, 1, INFOBYTES, ifp) != INFOBYTES) {
  271.         (void)fprintf(stderr, "Premature EOF\n");
  272. #ifdef SCAN
  273.         do_error("hexbin: Premature EOF");
  274. #endif /* SCAN */
  275.         exit(1);
  276.     }
  277.     ds = get4(header + I_DLENOFF);
  278.     rs = get4(header + I_RLENOFF);
  279.     ds = (((ds + 127) >> 7) << 7);
  280.     rs = (((rs + 127) >> 7) << 7);
  281.     to_read = ds + rs;
  282.     if(strncmp(header + I_TYPEOFF, "TEXT", 4)) {
  283.         (void)fprintf(stderr, "This file is not a proper BinHexed file.\n");
  284. #ifdef SCAN
  285.         do_error("hexbin: not a proper BinHexed file");
  286. #endif /* SCAN */
  287.         exit(1);
  288.     }
  289.  
  290.         if(listmode) {
  291.         (void)fprintf(stderr, "This file is probably packed by ");
  292.         if(!strncmp(header + I_AUTHOFF, "BNHQ", 4)) {
  293.         (void)fprintf(stderr, "\"BinHex\"");
  294.         } else if(!strncmp(header + I_AUTHOFF, "BthX", 4)) {
  295.         (void)fprintf(stderr, "\"BinHqx\"");
  296.         } else if(!strncmp(header + I_AUTHOFF, "BnHq", 4)) {
  297.         (void)fprintf(stderr, "\"StuffIt\"");
  298.         } else if(!strncmp(header + I_AUTHOFF, "ttxt", 4)) {
  299.         (void)fprintf(stderr, "\"Compactor\"");
  300.         } else if(!strncmp(header + I_AUTHOFF, "BSWU", 4)) {
  301.         (void)fprintf(stderr, "\"UUTool\"");
  302.         } else {
  303.         (void)fprintf(stderr, "an unknown program");
  304.         }
  305.         (void)fprintf(stderr, ".\n");
  306.     }
  307.     }
  308.     /*    look for "(This file ...)" or "(Convert with...)" line. */
  309.     /*    or for "begin " */
  310.     /*    dl format starts with a line containing only the symbols '@' to 'O',
  311.     or '|'. */
  312.     while(readline()) {
  313.     llen = strlen(line);
  314. #ifdef HQX
  315.     if((strncmp(line, "(This file", 10) == 0) ||
  316.         (strncmp(line, "(Convert with", 13) == 0)) {
  317.         if(verbose) {
  318.         (void)fprintf(stderr, "Skip:%s\n", line);
  319.         }
  320.         break;
  321.     }
  322. #endif /* HQX */
  323. #ifdef MU
  324.     if(strncmp(line, "begin ", 6) == 0) {
  325.         return form_mu;
  326.     }
  327. #endif /* MU */
  328. #ifdef DL
  329.     /* Do not allow bogus false starts */
  330.     if(llen > 40 && (llen & 1) == 0) {
  331.         dl_start = 1;
  332.         for(cp = &line[0]; *cp != 0; cp++) {
  333.         if((*cp < '@' || *cp > 'O') && *cp != '|') {
  334.             dl_start = 0;
  335.             break;
  336.         }
  337.         }
  338.         if(dl_start && cp > &line[1]) {
  339.         return form_dl;
  340.         }
  341.     }
  342. #endif /* DL */
  343.     if(llen != 0 && verbose) {
  344.         (void)fprintf(stderr, "Skip:%s\n", line);
  345.     }
  346.     }
  347.     while(readline()) {
  348.     switch (line[0]) {
  349. #ifdef HQX
  350.     case ':':
  351.         return form_hqx;
  352. #endif /* HQX */
  353. #ifdef HECX
  354.     case '#':
  355.         return form_hecx;
  356. #endif /* HECX */
  357.     default:
  358.         break;
  359.     }
  360.     }
  361.  
  362.     if(!again) {
  363.     (void)fprintf(stderr, "unexpected EOF\n");
  364. #ifdef SCAN
  365.     do_error("hexbin: unexpected EOF");
  366. #endif /* SCAN */
  367.     exit(1);
  368.     }
  369.     return form_none;
  370. }
  371.  
  372. static void usage()
  373. {
  374.     (void)fprintf(stderr, "Usage: hexbin [-%s] [filenames]\n", options);
  375.     (void)fprintf(stderr, "Use \"hexbin -H\" for help.\n");
  376. }
  377.  
  378.