home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / CMDS / modbust.lzh / MODBUSTER / modbuster.c < prev   
C/C++ Source or Header  |  1994-10-11  |  15KB  |  679 lines

  1. /*  ModBuster.c - split merged modules (IE: OS9Boot) into seperate modules
  2. **
  3. **  (C) Copyright 1993 HyperTech Software / Mike Haaland
  4. **
  5. */
  6.  
  7. /* Includes, defines */
  8.  
  9. #include <stdio.h>
  10. #include <ctype.h>
  11.  
  12. extern errno;
  13.  
  14. #ifndef TRUE
  15. #define TRUE     1
  16. #define FALSE    0
  17. #endif
  18.  
  19. #define SEEK_BEG 0
  20. #define SEEK_CUR 1
  21. #define SEEK_END 2
  22.  
  23. #define SAME     0
  24.  
  25. /* OSK modules */
  26. #define SYNC     0x4AFC
  27. #define SYNC1    0x4A
  28. #define OFFSET   16
  29.  
  30. /* CoCo modules */
  31. #define CSYNC    0x87CD
  32. #define CSYNC1   0x87
  33. #define COFFSET  6
  34.  
  35. /* OSK ROF (.r) */
  36. #define RSYNC    0xDEADFACE
  37. #define RSYNC1   0xDE
  38. #define ROFFSET  0x38
  39.  
  40. /* KWindows/Coco bitmaps */
  41. #define BITMP    0x1b
  42.  
  43. int  buffersize  = (1024 * 16);
  44. int  verbose     = FALSE;
  45. int  quiet       = FALSE;
  46. char *buffer     = NULL;
  47. char *dirname    = NULL;
  48. char flname[100];
  49. char name[256];
  50.  
  51. static char sccs[] = "(C) Copyright 1993 HyperTech Software / Mike Haaland";
  52.  
  53. /* Main call */
  54.  
  55. char *usgmsg[] = {
  56.     "Syntax: Modbuster [<opts>] <path> [<opts>]\n",
  57. #ifdef OSK
  58.     "Function: Seperate merged modules, rels, basic source or KWindows bitmaps\n",
  59. #else
  60.     "Function: Seperate merged modules, basic source or Multi-Vue bitmaps\n",
  61. #endif
  62.     "Options:\n",
  63.     "   -b=<size>  buffer size\n",
  64.     "   -q         quiet/silent mode\n",
  65.     "   -v         verbose\n",
  66.     "   -w=<dir>   seperate into <dir>\n",
  67.     "              (default = current work directory)\n",
  68.     NULL
  69. };
  70.  
  71. usage()
  72. {
  73.     int i = 0;
  74.  
  75.     while(usgmsg[i])
  76.         fputs(usgmsg[i++],stderr);
  77.     exit(0);
  78. }       
  79.  
  80. main(argc,argv)
  81. int argc;
  82. char *argv[];
  83. {
  84.     char *scan, **filename;
  85.     int  file_count, argn, i, bsize;
  86.  
  87.     if (argc < 2)
  88.         usage();
  89.  
  90.     file_count = 0;
  91.  
  92.     for (i = 1; i < argc ; i++ )
  93.         if (argv[i][0] != '-')
  94.             file_count++;
  95.  
  96.     if (file_count)
  97.         if ((filename = (char **)malloc(sizeof(char *) * file_count)) == NULL)
  98.             exit(_errmsg(errno,"Can't allocate memory - too many filenames"));
  99.  
  100.     file_count = 0;
  101.  
  102.     for (i = 1; i < argc ; i++ ) {
  103.         if (argv[i][0] == '-') {
  104.             scan = &argv[i][1]; 
  105.             while (*scan) {
  106.                 switch(toupper(*scan)) {
  107.                 case 'B' : 
  108.                     bsize = atoi(&scan[(scan[1] == '=') ? 2 : 1]) * 1024;
  109.                     if (bsize > buffersize)
  110.                         buffersize = bsize;
  111.                     scan[1] = NULL;
  112.                     break;
  113.                 case 'Q' :
  114.                     quiet   = TRUE;
  115.                     break;
  116.                 case 'V' :
  117.                     verbose = TRUE;
  118.                     break;
  119.                 case 'W' :
  120.                     dirname = &scan[(scan[1] == '=') ? 2 : 1];
  121.                     *scan-- = NULL;
  122.                     break;
  123.                 case '?' :
  124.                     usage();
  125.                     break;
  126.                 default  :
  127.                     exit(_errmsg(0,"Unknown option '-%c'\n",*scan));
  128.                 }
  129.                 scan++;
  130.             }
  131.         } 
  132.         else
  133.             filename[file_count++] = argv[i];
  134.     }
  135.  
  136.     if ( ! file_count )
  137.         exit(_errmsg(216,"No filename given!\n"));
  138.  
  139.     if ((buffer = (char *)malloc(buffersize + 2)) == NULL)
  140.         exit(_errmsg(errno,"Can't allocate buffer\n"));
  141.  
  142.     argn = 0;
  143.  
  144.     while (argn < file_count)
  145.         process(filename[argn++]);
  146. }
  147.  
  148. process(fname)
  149. char *fname;
  150. {
  151.     FILE          *fp;
  152.     unsigned char ch;
  153.  
  154.     if ((fp = fopen(fname,"r")) == NULL)
  155.         exit(_errmsg(errno,"Error opening '%s'\n",fname));
  156.  
  157.     if ((ch = fgetc(fp)) != EOF) {
  158.         fseek(fp,0L,SEEK_BEG);
  159.         switch(ch & 0xFF) {
  160. #ifdef OSK
  161.         case RSYNC1 :
  162.             do_rels(fp);
  163.             break;
  164. #endif
  165.         case CSYNC1 :
  166.             do_modules(fp,0);
  167.             break;
  168.         case SYNC1 :
  169.             do_modules(fp,1);
  170.             break;
  171.         case BITMP :
  172.             do_bitmaps(fp);
  173.             break;
  174.         default :
  175.             do_basic(fp);
  176.         }
  177.     }
  178.  
  179.     fclose(fp);
  180.     return(0);
  181. }
  182.  
  183. #ifdef OSK
  184. struct r_header {
  185.     unsigned long    rsync;
  186.     short            lang_type;
  187.     short            at_rv;
  188.     short            v_asm;
  189.     short            series;
  190.     char            time[6];
  191.     short            edition;
  192.     long            stat_size;
  193.     long            init_size;
  194.     long            obj_size;
  195.     long            stack_size;
  196.     long            entry_off;
  197.     long            tentry_off;
  198.     long            rstat_size;
  199.     long            rinit_size;
  200.     long            dbg_size;
  201. } r_hdr;
  202.  
  203.  
  204. /* Split OSK Relocatable Object Files (.r) */
  205. do_rels(fp)
  206. FILE *fp;
  207. {
  208.     FILE  *ofp;
  209.     int    size, length, i;
  210.     char   c, junk[80];
  211.     char   rname[40];
  212.     int    rnamelen;
  213.     char   *ptr;
  214.     short  num;
  215.     long   goback;
  216.     unsigned long sync;
  217.  
  218.     while (TRUE) {
  219.         sync = 0;
  220.         fread(&sync,1,sizeof(long),fp);
  221.         if (sync != RSYNC)
  222.             return(0);
  223.  
  224.         fseek(fp,-4,SEEK_CUR);
  225.  
  226.         fread(&r_hdr,1,sizeof(struct r_header),fp);
  227.  
  228.         i = 0;
  229.  
  230.         do {
  231.             c = fgetc(fp);
  232.             name[i++] = c;
  233.         } 
  234.         while (isprint(c));
  235.         
  236.         strcpy(rname,name);
  237.         rnamelen = i;
  238.  
  239.         name[--i] = name[i] & 0x7f;
  240.         name[++i] = '\0';
  241.  
  242.  
  243.         if ((ptr = (char *)rindex(name,'_')) != NULL && strlen(ptr) < 3)
  244.             strcpy(ptr,".r");
  245.         else
  246.             strcat(name,".r");
  247.  
  248.         if (dirname)
  249.             sprintf(flname,"%s/%s",dirname,name);
  250.         else
  251.             strcpy(flname,name);
  252.  
  253.         if ((ofp = fopen(flname,"w")) == NULL)
  254.             fprintf(stderr,"Can't create %s - Error %03d\n", flname,errno);
  255.  
  256.         if (ofp != NULL)
  257.             if (! quiet) 
  258.                 if (verbose)
  259.                     fprintf(stderr,"ROF: %s\n",name);
  260.                 else
  261.                     fprintf(stderr,"%s\n",name);
  262.  
  263.         fread(&num,1,sizeof(short),fp);
  264.  
  265.         if (ofp != NULL)
  266.         {
  267.            fwrite(&r_hdr,1,sizeof(r_hdr),ofp);
  268.            fwrite(rname,1,rnamelen,ofp);
  269.            fwrite(&num,1,sizeof(short),ofp);
  270.         }
  271. #ifdef DEBUG
  272.         fprintf(stderr,"%d external definitions\n",num);
  273.         fprintf(stderr,"so read %d bytes\n",num * 6);
  274. #endif
  275.         do_extdefs(fp,ofp,num);
  276.  
  277.         length = r_hdr.obj_size + r_hdr.init_size +
  278.             r_hdr.rinit_size + r_hdr.dbg_size;
  279. #ifdef DEBUG
  280.         fprintf(stderr,"%d bytes to be copied raw\n",length);
  281. #endif
  282.         do {
  283.             if (length > buffersize) {
  284.                 size = buffersize;
  285.                 length -= buffersize;
  286.             } 
  287.             else {
  288.                 size = length;
  289.                 length = 0;
  290.             }    
  291.             fread(buffer,1,size,fp);
  292.             if (ofp != NULL)
  293.                 fwrite(buffer,1,size,ofp);
  294.         } while (length);
  295.  
  296.         fread(&num,1,sizeof(short),fp);
  297.  
  298.         if (ofp != NULL)
  299.            fwrite(&num,1,sizeof(short),ofp);
  300.  
  301. #ifdef DEBUG
  302.         fprintf(stderr,"%d external references\n",num);
  303. #endif
  304.         do_extrefs(fp,ofp,num);
  305.     
  306.         fread(&num,1,sizeof(short),fp);
  307.  
  308.         if (ofp != NULL)
  309.            fwrite(&num,1,sizeof(short),ofp);
  310.  
  311. #ifdef DEBUG
  312.         fprintf(stderr,"%d local references\n",num);
  313. #endif
  314.         do_locrefs(fp,ofp,num);
  315.  
  316.         /* All RELs have 16 nulls of padding at the end */
  317.         fread(junk,1,16,fp);
  318.  
  319.         if (ofp != NULL)
  320.            fwrite(junk,1,16,ofp);
  321.  
  322.         if (ofp != NULL)
  323.             fclose(ofp);
  324.     }
  325. }
  326.  
  327. do_extdefs(fp,ofp,num)
  328. FILE *fp, *ofp;
  329. short num;
  330. {
  331.     int i;
  332.     char junk[6];
  333.     char c;
  334.  
  335.        while (num) {
  336.            i = 0;
  337.         do {
  338.             c = fgetc(fp);
  339.             name[i++] = c;
  340.         } while (isprint(c));
  341.         name[i] = '\0';
  342. #ifdef DEBUG
  343.         fprintf(stderr,"ext. def: %s\n",name);
  344. #endif
  345.            fread(junk,1,6,fp);
  346.         if (ofp != NULL)
  347.         {
  348.            fwrite(name,1,strlen(name) + 1,ofp);
  349.            fwrite(junk,1,6,ofp);
  350.         }
  351.         num--;
  352.     }
  353. }
  354.     
  355. do_extrefs(fp,ofp,num)
  356. FILE *fp, *ofp;
  357. short num;
  358. {
  359.     int   i;
  360.     char  c;
  361.     short cnt;
  362.  
  363.     while (num)
  364.     {
  365.         i = 0;
  366.         do {
  367.             c = fgetc(fp);
  368.             name[i++] = c;
  369.         } while (isprint(c));
  370.         name[i] = '\0';
  371.  
  372.         fread(&cnt,1,sizeof(short),fp);
  373. #ifdef DEBUG
  374.         fprintf(stderr,"ext. ref: %s\n",name);
  375. #endif
  376.         if (ofp != NULL)
  377.         {
  378.            fwrite(name,1,strlen(name) + 1,ofp);
  379.            fwrite(&cnt,1,sizeof(short),ofp);
  380.         }
  381.         do_locrefs(fp,ofp,cnt);
  382.         num--;
  383.     }
  384. }
  385.  
  386. do_locrefs(fp,ofp,num)
  387. FILE *fp, *ofp;
  388. short num;
  389. {
  390.     char junk[6];    
  391.  
  392. #ifdef DEBUG
  393.     fprintf(stderr,"%d refs, so read %d bytes\n",num, num * 6);
  394. #endif
  395.        while (num) {
  396.            fread(junk,1,6,fp);
  397.         if (ofp != NULL)
  398.            fwrite(junk,1,6,ofp);
  399.         num--;
  400.     }
  401. }
  402. #endif
  403.     
  404. /* Split Binary Object files (Modules) */
  405. do_modules(fp,osk)
  406. FILE *fp;
  407. int osk;
  408. {
  409.     FILE  *ofp;
  410.     int   size, length, noffset, i;
  411.     char  c, junk[4];
  412.     short sync;
  413.     long  goback;
  414.  
  415.     while (TRUE) { 
  416.         fread(&sync,1,sizeof(short),fp);
  417.         if (osk)
  418.         {
  419.             if (sync != SYNC)
  420.                 return(0);
  421.             fread(junk,2,sizeof(char),fp);
  422.             fread(&length,1,sizeof(int),fp);
  423.             fread(junk,4,sizeof(char),fp);
  424.             fread(&noffset,1,sizeof(int),fp);
  425.             goback = noffset;
  426.             fseek(fp,noffset - OFFSET,SEEK_CUR);
  427.         }
  428.         else
  429.         {
  430.             if (sync != CSYNC)
  431.                 return(0);
  432.             fread(&length,1,sizeof(int),fp);
  433.             fread(&noffset,1,sizeof(int),fp);
  434.             goback = noffset;
  435.             fseek(fp,noffset - COFFSET,SEEK_CUR);
  436.         }
  437.  
  438.         i = 0;
  439.  
  440.         do {
  441.             name[i++] = c = fgetc(fp);
  442.             goback++;
  443.         } 
  444.         while (isprint(c));
  445.  
  446.         name[--i] = name[i] & 0x7f;
  447.         name[++i] = '\0';
  448.         fseek(fp,-goback,SEEK_CUR);
  449.         if (dirname)
  450.             sprintf(flname,"%s/%s",dirname,name);
  451.         else
  452.             strcpy(flname,name);
  453.  
  454.         if ((ofp = fopen(flname,"w")) == NULL)
  455.             fprintf(stderr,"Can't create %s - Error %03d\n", flname,errno);
  456.  
  457.         if (ofp != NULL)
  458.             if (! quiet) 
  459.                 if (verbose)
  460.                     fprintf(stderr,"Module: %s\nLength: %d $%X\n",
  461.                         name,length,length);
  462.                 else
  463.                     fprintf(stderr,"%s\n",name);
  464.  
  465.         do {
  466.             if (length > buffersize) {
  467.                 size = buffersize;
  468.                 length -= buffersize;
  469.             } 
  470.             else {
  471.                 size = length;
  472.                 length = 0;
  473.             }    
  474.             fread(buffer,1,size,fp);
  475.             if (ofp != NULL)
  476.                 fwrite(buffer,1,size,ofp);
  477.         } while (length);
  478.  
  479.         if (ofp != NULL)
  480.             fclose(ofp);
  481.     }
  482. }
  483.  
  484. /* Split Microware Basic source */
  485. do_basic(fp)
  486. FILE *fp;
  487. {
  488.     FILE *ofp;
  489.     char c, *p, line[BUFSIZ];
  490.  
  491.     ofp = NULL;
  492.     
  493.     while (fgets(line,255,fp) != NULL) {
  494.         if (strncmp(line,"PROCEDURE ",10) == SAME) {
  495.             if (ofp != NULL)
  496.                 fclose(ofp);
  497.             strcpy(name,&line[10]);
  498.             if (p = (char *)index(name,'\n'))
  499.                 *p = '\0';
  500.             if (dirname)
  501.                 sprintf(flname,"%s/%s",dirname,name);
  502.             else
  503.                 strcpy(flname,name);
  504.  
  505.             if ((ofp = fopen(flname,"w")) == NULL)
  506.                 fprintf(stderr,"Can't create %s - Error #%03d\n",flname,errno);
  507.  
  508.             if (ofp != NULL)
  509.                 if (! quiet) 
  510.                     if (verbose)
  511.                         fprintf(stderr,"%s\n",line);
  512.                     else
  513.                         fprintf(stderr,"%s\n",name);
  514.         }
  515.         if (ofp != NULL)
  516.            fputs(line,ofp);
  517.     }
  518.     if (ofp != NULL)
  519.         fclose(ofp);
  520.     return(0);
  521. }
  522.  
  523. typedef struct {
  524.     short         ID;
  525.     unsigned char misc[9];
  526. } BITMAPHEAD;
  527.  
  528. BITMAPHEAD bm;
  529.  
  530. #define grp     misc[0]
  531. #define buf     misc[1]
  532. #define sty     misc[2]
  533. #define bm_xsiz ((bm.misc[3] << 8) | bm.misc[4])
  534. #define bm_ysiz ((bm.misc[5] << 8) | bm.misc[6])
  535. #define bm_blen ((bm.misc[7] << 8) | bm.misc[8])
  536.  
  537. #define GRP_FONT    200
  538. #define GRP_PTR16   201
  539. #define GRP_PTR256  202
  540. #define GRP_PAT2    203
  541. #define GRP_PAT4    204
  542. #define GRP_PAT16   205
  543.  
  544. /* Non CoCo group numbers */
  545. #define GRP_PAT256  206
  546. #define GRP_BRSH2   207
  547. #define GRP_BRSH4   208
  548. #define GRP_BRSH16  209 
  549. #define GRP_BRSH256 210
  550.  
  551. /* Merged Kwindows/Multi-view bitmaps */
  552. do_bitmaps(fp)
  553. FILE *fp;
  554. {
  555.     FILE  *ofp;
  556.     int   size, length;
  557.  
  558.     while (fread(&bm,sizeof(char),11,fp)) { 
  559.         if (bm.ID != 0x1B2B) {
  560.             fprintf(stderr,"Got sync of 0x%04X\n",bm.ID);
  561.             return(0);
  562.         }
  563.  
  564.         length = bm_blen;
  565.  
  566.         switch(bm.grp) {
  567.         case GRP_FONT   :
  568.             sprintf(name,"font%02X_%02X.fnt",bm.grp,bm.buf);
  569.             break;
  570.         case GRP_PTR16  :
  571.             sprintf(name,"stdptr16_%02X.ptr",bm.buf);
  572.             break;
  573.         case GRP_PTR256 :
  574.             sprintf(name,"stdptr256_%02X.ptr",bm.buf);
  575.             break;
  576.         case GRP_PAT2   :
  577.             sprintf(name,"stdpat2_%02X.pat",bm.buf);
  578.             break;
  579.         case GRP_PAT4   :
  580.             sprintf(name,"stdpat4_%02X.pat",bm.buf);
  581.             break;
  582.         case GRP_PAT16  :
  583.             sprintf(name,"stdpat16_%02X.pat",bm.buf);
  584.             break;
  585.         case GRP_PAT256 :
  586.             sprintf(name,"stdpat256_%02X.pat",bm.buf);
  587.             break;
  588.         case GRP_BRSH2  :
  589.             sprintf(name,"stdbrsh2_%02X.brsh",bm.buf);
  590.             break;
  591.         case GRP_BRSH4  :
  592.             sprintf(name,"stdbrsh4_%02X.brsh",bm.buf);
  593.             break;
  594.         case GRP_BRSH16 :
  595.             sprintf(name,"stdbrsh16_%02X.brsh",bm.buf);
  596.             break;
  597.         case GRP_BRSH256:
  598.             sprintf(name,"stdbrsh256_%02X.brsh",bm.buf);
  599.             break;
  600.         default :
  601.             sprintf(name,"misc%dc_%02X_%02X.buf",getsty(bm.sty),bm.grp,bm.buf);
  602.         }
  603.  
  604.         if (dirname)
  605.             sprintf(flname,"%s/%s",dirname,name);
  606.         else
  607.             strcpy(flname,name);
  608.  
  609.         if ((ofp = fopen(flname,"w")) == NULL)
  610.             fprintf(stderr,"Can't create %s - Error %03d\n", flname,errno);
  611.  
  612.         if (ofp != NULL) {
  613.             fwrite(&bm,sizeof(char),11,ofp);
  614.  
  615.             if (! quiet)
  616.                 if (verbose) {
  617.                     fprintf(stderr,"Name:    %s\n",name);
  618.                     fprintf(stderr,"Grp/Buf: $%02X/$%02X\n",bm.grp,bm.buf);
  619.                     fprintf(stderr,"Size:    %d x %d\n",bm_xsiz,bm_ysiz);
  620.                     fprintf(stderr,"STY:     %02d\n",bm.sty);
  621.                     fprintf(stderr,"Colors:  %d\n",getsty(bm.sty));
  622.                     fprintf(stderr,"Length:  %d $%X\n\n",length,length);
  623.                 } else
  624.                     fprintf(stderr,"%s\n",name);
  625.         }
  626.         
  627.         do {
  628.             if (length > buffersize) {
  629.                 size = buffersize;
  630.                 length -= buffersize;
  631.             } 
  632.             else {
  633.                 size = length;
  634.                 length = 0;
  635.             }    
  636.             fread(buffer,1,size,fp);
  637.             if (ofp != NULL)
  638.                 fwrite(buffer,1,size,ofp);
  639.         } while (length);
  640.  
  641.         if (ofp != NULL)
  642.             fclose(ofp);
  643.         bm.ID = 0;
  644.     }
  645.     return(0);
  646. }    
  647.  
  648. getsty(styp)
  649. char styp;
  650. {
  651.     int colors;
  652.     
  653.     switch (styp) {
  654.     case 0:   /* Kwindow fonts */
  655.         colors = 2;
  656.         break;
  657.     case 3:   /* Kwindow bitmaps */
  658.         colors = 256;
  659.         break;
  660.     case 4:   /* Coco bitmaps */
  661.     case 5:
  662.         colors = 2;
  663.         break;
  664.     case 6:   /* Coco bitmaps */
  665.     case 7:
  666.         colors = 4;
  667.         break;
  668.     case 8:   /* Coco or Kwindow bitmaps */
  669.         colors = 16;
  670.         break;
  671.     default:
  672.         colors = 0;
  673.     }
  674.     return (colors);
  675. }
  676.         
  677. /* End */
  678.  
  679.