home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / findhit / findhit.c < prev    next >
C/C++ Source or Header  |  1998-11-19  |  6KB  |  329 lines

  1. #include "headers.h"
  2.  
  3. #define VERSION "37.1"
  4.  
  5. struct GlobalData {
  6.     struct Library *SysBase;
  7.     struct Library *DOSBase;
  8.  
  9.     ULONG hunk;
  10.     BOOL delete_omdfile;
  11.  
  12.     UBYTE omdfile[36];    /* keep the mapfilename to delete if delete_omdfile is TRUE */
  13.     
  14.     UBYTE buffer[512];
  15. };
  16. typedef struct GlobalData GLOB;
  17.  
  18. static UBYTE *ver= "$VER: FindHit " VERSION " (26.3.93)";
  19.  
  20. static LONG find_hit_from_map(GLOB *z, UBYTE *mapfile, UBYTE *offset);
  21. static LONG find_offset_from_omd(GLOB *z, UBYTE *ofile, UBYTE *cfile, ULONG base, ULONG hit_offset);
  22. static BOOL diff_time(GLOB *z, UBYTE *file1, UBYTE *file2);
  23. static LONG hexToLong(UBYTE *str);
  24. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...);
  25.  
  26. #define TEMPLATE "MAPFILE/A,OFFSET/A/M,HUNK/N,DEL=DELETEOMDFILE/S"
  27. #define OPT_MAPFILE        0
  28. #define OPT_OFFSET        1
  29. #define OPT_HUNK        2
  30. #define OPT_DELETE        3
  31. #define OPT_COUNT        4
  32. LONG StartUpCode(void)
  33. {
  34.   GLOB *z;
  35.   struct Library *SysBase=*((void **)4L);
  36.   struct RDArgs *rdargs;
  37.   UBYTE **str;
  38.   LONG opts[OPT_COUNT];
  39.   LONG retval=RETURN_FAIL;
  40.  
  41.  
  42.     if( z=AllocMem(sizeof(GLOB),MEMF_ANY) )
  43.         {
  44.         z->SysBase= SysBase;
  45. #define DOSBase z->DOSBase
  46. #define SysBase z->SysBase
  47.         if( DOSBase=OpenLibrary("dos.library", 37L) )
  48.             {
  49.             memset(opts, 0, sizeof(opts));
  50.             if( rdargs=ReadArgs(TEMPLATE, opts, NULL) )
  51.                 {
  52.                 
  53.                 if( opts[OPT_HUNK] )
  54.                     {
  55.                     z->hunk= *((LONG *)opts[OPT_HUNK]);
  56.                     }
  57.                 else
  58.                     {
  59.                     z->hunk= 0;
  60.                     }
  61.                 if( opts[OPT_DELETE] )
  62.                     {
  63.                     z->delete_omdfile=TRUE;
  64.                     }
  65.                 else
  66.                     {
  67.                     z->delete_omdfile=FALSE;
  68.                     }
  69.  
  70.                 Printf("\2331m_FindHit_\2330m " VERSION " by Douglas Keller\n\n");
  71.  
  72.                 str= (UBYTE **) opts[OPT_OFFSET];
  73.                 while( *str )
  74.                     {
  75.                     if( retval= find_hit_from_map(z, (UBYTE *)opts[OPT_MAPFILE], *str) )
  76.                         {
  77.                         break;
  78.                         }
  79.                     str++;
  80.                     }
  81.  
  82.                 if( z->delete_omdfile ) DeleteFile(z->omdfile);
  83.  
  84.                 Printf("\n");
  85.                 
  86.                 FreeArgs(rdargs);
  87.                 }
  88.             else
  89.                 {
  90.                 PrintFault(IoErr(), NULL);
  91.                 }
  92.  
  93.             CloseLibrary(DOSBase);
  94.             }
  95.         FreeMem(z, sizeof(GLOB));
  96.         }
  97.     return( retval );
  98. }
  99.  
  100. static LONG find_hit_from_map(GLOB *z, UBYTE *mapfile, UBYTE *offset_str)
  101. {
  102.   BPTR fh;
  103.   BPTR lock, old_cd;
  104.   UBYTE *buffer= z->buffer;
  105.   UBYTE *ptr, cfile[32], ofile[32], *lastchar;
  106.   BOOL start=FALSE;
  107.   BOOL hunkfound=FALSE;
  108.   ULONG hit_offset;
  109.   ULONG offset, lastoffset=0;
  110.   LONG retval=RETURN_FAIL;
  111.   UBYTE path[256];
  112.  
  113.  
  114.     hit_offset= hexToLong(offset_str);
  115.     strcpy(path, mapfile);
  116.     *(PathPart(path))= NULL;
  117.     if( lock=Lock(path,SHARED_LOCK) )  /* CD to mapfile dir, so we can find #?.(c|o) files */
  118.         {
  119.         old_cd= CurrentDir(lock);
  120.         }
  121.  
  122.     if( fh=Open(mapfile, MODE_OLDFILE) )
  123.         {
  124.         SetVBuf(fh, NULL, BUF_FULL, 4096);
  125.         while( FGets(fh, buffer, 100) )
  126.             {
  127.             if( !start && buffer[0]==' '&&buffer[1]=='n'&&buffer[2]=='u'&&buffer[3]=='m' )
  128.                 {
  129.                 start=TRUE;
  130.                 continue;
  131.                 }
  132.             else if( start && buffer[0]==0x0c )
  133.                 {
  134.                 start=FALSE;
  135.                 continue;
  136.                 }
  137.  
  138.             if( start && !hunkfound )
  139.                 {
  140.                 if( buffer[3] != ' ' )
  141.                     {
  142.                     buffer[4]= NULL;
  143.                     if( z->hunk == hexToLong(buffer) )
  144.                         {
  145.                         hunkfound=TRUE;
  146.                         }
  147.                     }
  148.                 }
  149.             else if( start && hunkfound )
  150.                 {
  151.                 ptr= buffer+23;
  152.                 while( *++ptr != ' ' )
  153.                     {
  154.                     }
  155.                 *ptr=
  156.                 buffer[66]= NULL;
  157.                 ptr= buffer+23;
  158.                 offset= hexToLong(buffer+60);
  159.  
  160.                 if( offset > hit_offset )
  161.                     {
  162.                     Printf("Found offset 0x%08lx in \"%s\", ", hit_offset, cfile);
  163.                     Flush(Output());
  164.  
  165.                     retval= find_offset_from_omd(z, ofile, cfile, lastoffset, hit_offset);
  166.  
  167.                     break;
  168.                     }
  169.  
  170.                 strcpy(ofile, ptr);
  171.                 strcpy(cfile, ptr);
  172.                 lastchar= cfile + strlen(cfile)-1;
  173.                 if( *lastchar == 'o' ) *lastchar='c';
  174.                 lastoffset= offset;
  175.                 }
  176.  
  177.             }
  178.         Close(fh);        
  179.         }
  180.     else
  181.         {
  182.         Printf("Error: could not open mapfile '%s'\n", mapfile);
  183.         }
  184.  
  185.     if( old_cd )
  186.         {
  187.         CurrentDir(old_cd);
  188.         }
  189.  
  190.     return( retval );
  191. }
  192.  
  193. #define SEMICOLON 1
  194. #define VERTBAR   2
  195.  
  196. static LONG find_offset_from_omd(GLOB *z, UBYTE *ofile, UBYTE *cfile, ULONG base, ULONG hit_offset)
  197. {
  198.   BPTR clock, olock;
  199.   BPTR fh;
  200.   ULONG line_num=0,found_line=0;
  201.   ULONG offset;
  202.   UBYTE *buffer= z->buffer;
  203.   UWORD last=0;
  204.   UBYTE *omdfile=z->omdfile;
  205.   LONG retval=RETURN_FAIL;
  206.   LONG system_retval=0;
  207.  
  208.     if( clock=Lock(cfile, SHARED_LOCK) )
  209.         {
  210.         if( olock=Lock(ofile, SHARED_LOCK) )
  211.             {
  212.             SPrintf(SysBase, omdfile, "t:fh_%s", cfile);
  213.             strcpy(omdfile+strlen(omdfile)-1, "omd");
  214.  
  215.             if( diff_time(z, ofile, omdfile) )
  216.                 {
  217.                 SPrintf(SysBase, buffer, "omd \"%s\" \"%s\" >%s", ofile, cfile, omdfile);
  218.                 system_retval=SystemTags(buffer,
  219.                                     SYS_UserShell, TRUE,
  220.                                     TAG_DONE);
  221.                 if( system_retval )
  222.                     {
  223.                     DeleteFile(omdfile);
  224.                     Printf("Error: error running OMD.\n");
  225.                     }
  226.                 }
  227.  
  228.             if( system_retval==0 && (fh=Open(omdfile, MODE_OLDFILE)) )
  229.                 {
  230.                 SetVBuf(fh, NULL, BUF_FULL, 4096);
  231.                 retval= RETURN_WARN;
  232.  
  233.                 while( FGets(fh, buffer, 100) )
  234.                     {
  235.                     if( buffer[0] == ';' )
  236.                         {
  237.                         line_num++;
  238.                         last= SEMICOLON;
  239.                         }
  240.                     if( buffer[7] == '|' )
  241.                         {
  242.                         buffer[13]= NULL;
  243.                         offset= hexToLong(buffer+9);
  244.  
  245.                         if( base + offset >= hit_offset )
  246.                             {
  247.                             Printf("on line %ld\n", found_line);
  248.                             retval=RETURN_OK;
  249.                             break;
  250.                             }
  251.  
  252.                         if( last == SEMICOLON ) found_line= line_num;
  253.                         last= VERTBAR;
  254.                         }
  255.                     }
  256.  
  257.                 if( retval != RETURN_OK ) Printf("line number not found.\n");
  258.  
  259.                 Close(fh);
  260.                 }
  261.  
  262.             UnLock(olock);
  263.             }
  264.         else
  265.             {
  266.             Printf("Error: could not open \"%s\".\n", ofile);
  267.             }
  268.         UnLock(clock);
  269.         }
  270.     else
  271.         {
  272.         Printf("Error: could not open \"%s\".\n", cfile);
  273.         }
  274.     return( retval );
  275. }
  276.  
  277. static BOOL diff_time(GLOB *z, UBYTE *file1, UBYTE *file2)
  278. {
  279.   BPTR lock1;
  280.   BPTR lock2;
  281.   struct FileInfoBlock __aligned fib1;
  282.   struct FileInfoBlock __aligned fib2;
  283.   BOOL retval=TRUE;
  284.  
  285.     if( lock1=Lock(file1,SHARED_LOCK) )
  286.         {
  287.         if( lock2=Lock(file2,SHARED_LOCK) )
  288.             {
  289.             if( Examine(lock1,&fib1) && Examine(lock2,&fib2) )
  290.                 {
  291.                 if( 0 <= CompareDates(&fib1.fib_Date, &fib2.fib_Date) )
  292.                     {
  293.                     retval=FALSE;
  294.                     }
  295.                 }
  296.             UnLock(lock2);
  297.             }
  298.         UnLock(lock1);
  299.         }
  300.     return( retval );
  301. }
  302.  
  303. static LONG hexToLong(UBYTE *str)
  304. {
  305.   LONG num;
  306.  
  307.     while( *str == ' ' )
  308.         {
  309.         str++;
  310.         }
  311.  
  312.     stch_l(str, &num);
  313.     return( num );
  314. }
  315.  
  316. extern void __builtin_emit(int);
  317. static void sPutC(void)
  318. {
  319.     __builtin_emit(0x16c0);
  320. }
  321.  
  322. #undef SysBase
  323. static void SPrintf(struct Library *SysBase, STRPTR buffer, STRPTR format, ...)
  324. {
  325.  
  326.     RawDoFmt( format, (APTR)(&format+1), sPutC, buffer);
  327. }
  328.  
  329.