home *** CD-ROM | disk | FTP | other *** search
/ Otherware / Otherware_1_SB_Development.iso / mac / util / unix / macutil2.sha / macutil / hexbin / hexbin.c < prev    next >
Encoding:
C/C++ Source or Header  |  1992-11-05  |  7.6 KB  |  363 lines

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